v5.12.0
5.12.0 20180209 * Change library PubSubClient.h define MQTT_MAX_PACKET_SIZE from 512 to 1000 for Home Assistant support * Change relation of define MESSZ being dependent on PubSubClient.h define MQTT_MAX_PACKET_SIZE * Change command color parameter input checks to less strict for Home Assistant support * Change command Ina219Mode into command Sensor13 * Change commands HlwPCal, HlwUCal and HlwICal to PowerCal, VoltageCal and CurrentCal to be used for both Pow and S31 calibration * Change commands HlwPSet, HlwUSet and HlwISet to PowerSet, VoltageSet and CurrentSet to be used for both Pow and S31 calibration * Change uptime from hour to second resulting in a display of 123T13:45:21 where 123 is days * Change module name Wemos D1 mini into Generic (#1220) * Change HTML from width=100% to style=width:100% supporting HTML5 (#1358) * Change OSWATCH_RESET_TIME (Blocked loop) from 30 to 120 seconds to allow slow networks (#1556) * Change WIFI_MANAGER_SEC into WIFI_CONFIG_SEC (#1616) * Change function pointers code to save code space and memory (#1683) * Change webserver argument processing gaining 5k code space (#1705) * Change weblog memory usage (#1730, #1793, #1819) * Update TasmotaSerial library to 1.1.0 * Update language files Italian (#1594), Dutch (#1723) and Spanish (#1722) * Fix Non-English JSON temperature unit attachement * Fix Arilux RF induced exception by moving interrupt handler to iram on non ESP8266/Arduino lib v2.3.0 * Fix truncated command names and wrong response for DomoticzSwitchIdx (#1571) * Fix %-sign issue as printf escape character in Humidity and Sonoff SC (#1579) * Fix DS18B20 temperature JSON decimal dot (#1561) * Fix Energy JSON message (#1621) * Fix IRSend parameter translation (#1636) * Fix TSL2561 device detection (#1644, #1825) * Fix BME680 teleperiod resistance measuring (#1647) * Fix Energy Monitoring Energy Today and Energy Total reading after restart (#1648) * Fix IRReceive Data value (#1663) * Fix Energy Monitoring Energy Period roll-over (#1688) * Fix compiler warnings (#1774) * Fix command PWM response if no PWM channel is configured (#1783) * Add locale Decimal Separator to Web sensor page * Add ColorTemperature to light status message * Add command PowerOnState option 5 which inverts PulseTime and allows for delayed always on after power on * Add OtaMagic two step Web server OTA upgrade using filename-minimal image if OTA free space is too small * Add support for PMS5003 and PMS7003 particle concentration sensor * Add command SetOption21 1 to allow Energy Monitoring when power is off on Sonoff Pow and Sonoff S31 (#1420) * Add Chinese language file (#1551) * Add French language file (#1561) * Add Spanish language file (#1589) * Add HTTP Allow Cross Origin removed from ESP8266/Arduino lib v2.4.0 (#1572) * Add Home Assistant MQTT Discovery for switch and light to be enabled by command SetOption19 1 (#1534) or define HOME_ASSISTANT_DISCOVERY_ENABLE in user_config.h (#1685) * Add command State to retrieve device state information (same data as teleperiod state and status 11 in slightly different JSON format) * Add optional login to Webserver AP mode (#1587, #1635) * Add command Sensor15 2 to start MHZ19(B) Zero Point Calibration (#1643) * Add support for Sonoff S31 Smart Socket with Power Consumption Detection (#1626) * Add command SetOption20 to allow update of Dimmer/Color/Ct without turning power on (#1719, #1741) * Add NTP sync time slot based on chip id (#1773) * Add cursor pointer to web button (#1836)
This commit is contained in:
parent
f60c570eac
commit
600c4b1872
@ -1,7 +1,7 @@
|
||||
## Sonoff-Tasmota
|
||||
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
|
||||
|
||||
Current version is **5.11.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
||||
Current version is **5.12.0** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
||||
|
||||
### ATTENTION All versions
|
||||
|
||||
@ -43,6 +43,7 @@ The following devices are supported:
|
||||
- [iTead Sonoff 4CH Pro](https://www.itead.cc/smart-home/sonoff-4ch-pro.html)
|
||||
- [iTead S20 Smart Socket](https://www.itead.cc/smart-socket.html)
|
||||
- [Sonoff S22 Smart Socket](https://github.com/arendst/Sonoff-Tasmota/issues/627)
|
||||
- [iTead Sonoff S31 Smart Socket with Energy Monitoring](https://www.itead.cc/sonoff-s31.html)
|
||||
- [iTead Slampher](https://www.itead.cc/slampher.html)
|
||||
- [iTead Sonoff Touch](https://www.itead.cc/sonoff-touch.html)
|
||||
- [iTead Sonoff T1](https://www.itead.cc/sonoff-t1.html)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,131 +0,0 @@
|
||||
|
||||
# ESP8266 platform
|
||||
# ------------------------------
|
||||
|
||||
# For more info:
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=ESP8266 Modules
|
||||
version=2.4.0
|
||||
|
||||
|
||||
|
||||
|
||||
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_flags=-DLWIP_OPEN_SRC
|
||||
|
||||
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}/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 -ffunction-sections -fdata-sections
|
||||
|
||||
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 call_user_start -u _printf_float -u _scanf_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 -laxtls -lespnow -lsmartconfig -lmesh -lwpa2 -lstdc++ -lm -lc -lgcc
|
||||
|
||||
compiler.cpp.cmd=xtensa-lx106-elf-g++
|
||||
compiler.cpp.flags=-c {compiler.warning_flags} -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -MMD -ffunction-sections -fdata-sections
|
||||
|
||||
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
|
||||
|
||||
## windows-compatible version may be added later
|
||||
|
||||
|
||||
## 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}" {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}" {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}" {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} "{build.path}/arduino.ar" "{object_file}"
|
||||
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/arduino.ar" {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.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
|
||||
|
||||
## 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}" -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"
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,131 +0,0 @@
|
||||
|
||||
# ESP8266 platform
|
||||
# ------------------------------
|
||||
|
||||
# For more info:
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=ESP8266 Modules
|
||||
version=2.4.0
|
||||
|
||||
|
||||
|
||||
|
||||
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_flags=-DLWIP_OPEN_SRC
|
||||
|
||||
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}/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 -ffunction-sections -fdata-sections
|
||||
|
||||
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 call_user_start -u _printf_float -u _scanf_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 -laxtls -lespnow -lsmartconfig -lairkiss -lmesh -lwpa2 -lstdc++ -lm -lc -lgcc
|
||||
|
||||
compiler.cpp.cmd=xtensa-lx106-elf-g++
|
||||
compiler.cpp.flags=-c {compiler.warning_flags} -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -MMD -ffunction-sections -fdata-sections
|
||||
|
||||
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
|
||||
|
||||
## windows-compatible version may be added later
|
||||
|
||||
|
||||
## 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}" {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}" {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}" {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} "{build.path}/arduino.ar" "{object_file}"
|
||||
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/arduino.ar" {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.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
|
||||
|
||||
## 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}" -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"
|
||||
@ -24,7 +24,8 @@
|
||||
// MQTT_MAX_PACKET_SIZE : Maximum packet size
|
||||
#ifndef MQTT_MAX_PACKET_SIZE
|
||||
//#define MQTT_MAX_PACKET_SIZE 128
|
||||
#define MQTT_MAX_PACKET_SIZE 512
|
||||
//#define MQTT_MAX_PACKET_SIZE 512 // Tasmota
|
||||
#define MQTT_MAX_PACKET_SIZE 1000 // Tasmota v5.11.1c
|
||||
#endif
|
||||
|
||||
// MQTT_KEEPALIVE : keepAlive interval in Seconds
|
||||
|
||||
@ -82,35 +82,56 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin)
|
||||
if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) {
|
||||
return;
|
||||
}
|
||||
m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE);
|
||||
if (m_buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
m_valid = true;
|
||||
m_rx_pin = receive_pin;
|
||||
m_tx_pin = transmit_pin;
|
||||
m_in_pos = m_out_pos = 0;
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
||||
pinMode(m_rx_pin, INPUT);
|
||||
ObjList[m_rx_pin] = this;
|
||||
attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING);
|
||||
pinMode(m_tx_pin, OUTPUT);
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
if (m_rx_pin > -1) {
|
||||
m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE);
|
||||
if (m_buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
||||
pinMode(m_rx_pin, INPUT);
|
||||
ObjList[m_rx_pin] = this;
|
||||
attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING);
|
||||
}
|
||||
if (m_tx_pin > -1) {
|
||||
pinMode(m_tx_pin, OUTPUT);
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
}
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
bool TasmotaSerial::isValidGPIOpin(int pin)
|
||||
{
|
||||
return (pin >= 0 && pin <= 5) || (pin >= 12 && pin <= 15);
|
||||
return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15);
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin(long speed) {
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /speed;
|
||||
return m_valid && (speed <= TM_SERIAL_BAUDRATE);
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin() {
|
||||
return m_valid;
|
||||
return begin(TM_SERIAL_BAUDRATE);
|
||||
}
|
||||
|
||||
void TasmotaSerial::flush() {
|
||||
m_in_pos = m_out_pos = 0;
|
||||
}
|
||||
|
||||
int TasmotaSerial::peek() {
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) {
|
||||
return -1;
|
||||
}
|
||||
return m_buffer[m_out_pos];
|
||||
}
|
||||
|
||||
int TasmotaSerial::read()
|
||||
{
|
||||
if (m_in_pos == m_out_pos) {
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) {
|
||||
return -1;
|
||||
}
|
||||
uint8_t ch = m_buffer[m_out_pos];
|
||||
@ -127,11 +148,17 @@ int TasmotaSerial::available()
|
||||
return avail;
|
||||
}
|
||||
|
||||
//#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts
|
||||
#else
|
||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bit_time; }
|
||||
#endif
|
||||
|
||||
size_t TasmotaSerial::txWrite(uint8_t b)
|
||||
size_t TasmotaSerial::write(uint8_t b)
|
||||
{
|
||||
if (-1 == m_tx_pin) {
|
||||
return 0;
|
||||
}
|
||||
unsigned long wait = m_bit_time;
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
unsigned long start = ESP.getCycleCount();
|
||||
@ -149,17 +176,6 @@ size_t TasmotaSerial::txWrite(uint8_t b)
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t TasmotaSerial::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
size_t n = 0;
|
||||
// Flush input buffer on every write
|
||||
m_in_pos = m_out_pos = 0;
|
||||
while(size--) {
|
||||
n += txWrite(*buffer++);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
void ICACHE_RAM_ATTR TasmotaSerial::rxRead()
|
||||
{
|
||||
@ -183,7 +199,7 @@ void TasmotaSerial::rxRead()
|
||||
TM_SERIAL_WAIT;
|
||||
// Store the received value in the buffer unless we have an overflow
|
||||
int next = (m_in_pos+1) % TM_SERIAL_BUFFER_SIZE;
|
||||
if (next != m_out_pos) {
|
||||
if (next != (int)m_out_pos) {
|
||||
m_buffer[m_in_pos] = rec;
|
||||
m_in_pos = next;
|
||||
}
|
||||
@ -20,25 +20,37 @@
|
||||
#ifndef TasmotaSerial_h
|
||||
#define TasmotaSerial_h
|
||||
/*********************************************************************************************\
|
||||
* TasmotaSerial supports 9600 baud with fixed buffer size of 20 bytes using optional no iram
|
||||
* TasmotaSerial supports up to 9600 baud with fixed buffer size of 64 bytes using optional no iram
|
||||
*
|
||||
* Based on EspSoftwareSerial v3.3.1 by Peter Lerup (https://github.com/plerup/espsoftwareserial)
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define TM_SERIAL_BAUDRATE 9600
|
||||
#define TM_SERIAL_BUFFER_SIZE 20
|
||||
//#define TM_SERIAL_USE_IRAM // Enable to use iram (+368 bytes)
|
||||
#define TM_SERIAL_BAUDRATE 9600 // Max supported baudrate
|
||||
#define TM_SERIAL_BUFFER_SIZE 64 // Receive buffer size
|
||||
|
||||
class TasmotaSerial {
|
||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
#define TM_SERIAL_USE_IRAM // Enable to use iram (+368 bytes)
|
||||
#endif
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
class TasmotaSerial : public Stream {
|
||||
public:
|
||||
TasmotaSerial(int receive_pin, int transmit_pin);
|
||||
bool begin(long speed);
|
||||
bool begin();
|
||||
size_t write(const uint8_t *buffer, size_t size = 1);
|
||||
int read();
|
||||
int available();
|
||||
int peek();
|
||||
|
||||
virtual size_t write(uint8_t byte);
|
||||
virtual int read();
|
||||
virtual int available();
|
||||
virtual void flush();
|
||||
|
||||
void rxRead();
|
||||
|
||||
using Print::write;
|
||||
|
||||
private:
|
||||
bool isValidGPIOpin(int pin);
|
||||
size_t txWrite(uint8_t byte);
|
||||
@ -12,19 +12,24 @@ src_dir = sonoff
|
||||
|
||||
; *** Uncomment one of the lines below to build/upload only one environment
|
||||
;env_default = sonoff
|
||||
;env_default = sonoff-NL
|
||||
;env_default = sonoff-CN
|
||||
;env_default = sonoff-DE
|
||||
;env_default = sonoff-PL
|
||||
;env_default = sonoff-ES
|
||||
;env_default = sonoff-FR
|
||||
;env_default = sonoff-IT
|
||||
;env_default = sonoff-NL
|
||||
;env_default = sonoff-PL
|
||||
;env_default = sonoff-minimal
|
||||
;env_default = sonoff-ds18x20
|
||||
|
||||
[env:sonoff]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=512
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
@ -33,6 +38,8 @@ monitor_baud = 115200
|
||||
|
||||
; *** Upload Serial reset method for Wemos and NodeMCU
|
||||
;upload_resetmethod = nodemcu
|
||||
;upload_port = COM6
|
||||
;upload_speed = 115200
|
||||
|
||||
; *** Upload file to OTA server using SCP
|
||||
;upload_port = user@host:/path
|
||||
@ -42,56 +49,101 @@ monitor_baud = 115200
|
||||
;upload_port = domus1:80/api/upload-arduino.php
|
||||
;extra_scripts = pio/strip-floats.py, pio/http-uploader.py
|
||||
|
||||
[env:sonoff-DE]
|
||||
[env:sonoff-CN]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=512 -DMY_LANGUAGE=de-DE
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DMY_LANGUAGE=zh-CN
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-DE]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DMY_LANGUAGE=de-DE
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-ES]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DMY_LANGUAGE=es-AR
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-FR]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DMY_LANGUAGE=fr-FR
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-IT]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=512 -DMY_LANGUAGE=it-IT
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DMY_LANGUAGE=it-IT
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-NL]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=512 -DMY_LANGUAGE=nl-NL
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DMY_LANGUAGE=nl-NL
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-PL]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=512 -DMY_LANGUAGE=pl-PL
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DMY_LANGUAGE=pl-PL
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-minimal]
|
||||
platform = espressif8266
|
||||
platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
;platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=512 -DBE_MINIMAL
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DBE_MINIMAL
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
[env:sonoff-ds18x20]
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
board = esp01_1m
|
||||
board_flash_mode = dout
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=707 -DUSE_DS18x20 -DMESSZ=600
|
||||
build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMQTT_MAX_PACKET_SIZE=1000 -DUSE_DS18x20
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
extra_scripts = pio/strip-floats.py
|
||||
|
||||
@ -1,4 +1,54 @@
|
||||
/* 5.11.1 20180107
|
||||
/* 5.12.0 20180209
|
||||
* Change library PubSubClient.h define MQTT_MAX_PACKET_SIZE from 512 to 1000 for Home Assistant support
|
||||
* Change relation of define MESSZ being dependent on PubSubClient.h define MQTT_MAX_PACKET_SIZE
|
||||
* Change command color parameter input checks to less strict for Home Assistant support
|
||||
* Change command Ina219Mode into command Sensor13
|
||||
* Change commands HlwPCal, HlwUCal and HlwICal to PowerCal, VoltageCal and CurrentCal to be used for both Pow and S31 calibration
|
||||
* Change commands HlwPSet, HlwUSet and HlwISet to PowerSet, VoltageSet and CurrentSet to be used for both Pow and S31 calibration
|
||||
* Change uptime from hour to second resulting in a display of 123T13:45:21 where 123 is days
|
||||
* Change module name Wemos D1 mini into Generic (#1220)
|
||||
* Change HTML from width=100% to style=width:100% supporting HTML5 (#1358)
|
||||
* Change OSWATCH_RESET_TIME (Blocked loop) from 30 to 120 seconds to allow slow networks (#1556)
|
||||
* Change WIFI_MANAGER_SEC into WIFI_CONFIG_SEC (#1616)
|
||||
* Change function pointers code to save code space and memory (#1683)
|
||||
* Change webserver argument processing gaining 5k code space (#1705)
|
||||
* Change weblog memory usage (#1730, #1793, #1819)
|
||||
* Update TasmotaSerial library to 1.1.0
|
||||
* Update language files Italian (#1594), Dutch (#1723) and Spanish (#1722)
|
||||
* Fix Non-English JSON temperature unit attachement
|
||||
* Fix Arilux RF induced exception by moving interrupt handler to iram on non ESP8266/Arduino lib v2.3.0
|
||||
* Fix truncated command names and wrong response for DomoticzSwitchIdx (#1571)
|
||||
* Fix %-sign issue as printf escape character in Humidity and Sonoff SC (#1579)
|
||||
* Fix DS18B20 temperature JSON decimal dot (#1561)
|
||||
* Fix Energy JSON message (#1621)
|
||||
* Fix IRSend parameter translation (#1636)
|
||||
* Fix TSL2561 device detection (#1644, #1825)
|
||||
* Fix BME680 teleperiod resistance measuring (#1647)
|
||||
* Fix Energy Monitoring Energy Today and Energy Total reading after restart (#1648)
|
||||
* Fix IRReceive Data value (#1663)
|
||||
* Fix Energy Monitoring Energy Period roll-over (#1688)
|
||||
* Fix compiler warnings (#1774)
|
||||
* Fix command PWM response if no PWM channel is configured (#1783)
|
||||
* Add locale Decimal Separator to Web sensor page
|
||||
* Add ColorTemperature to light status message
|
||||
* Add command PowerOnState option 5 which inverts PulseTime and allows for delayed always on after power on
|
||||
* Add OtaMagic two step Web server OTA upgrade using filename-minimal image if OTA free space is too small
|
||||
* Add support for PMS5003 and PMS7003 particle concentration sensor
|
||||
* Add command SetOption21 1 to allow Energy Monitoring when power is off on Sonoff Pow and Sonoff S31 (#1420)
|
||||
* Add Chinese language file (#1551)
|
||||
* Add French language file (#1561)
|
||||
* Add Spanish language file (#1589)
|
||||
* Add HTTP Allow Cross Origin removed from ESP8266/Arduino lib v2.4.0 (#1572)
|
||||
* Add Home Assistant MQTT Discovery for switch and light to be enabled by command SetOption19 1 (#1534) or define HOME_ASSISTANT_DISCOVERY_ENABLE in user_config.h (#1685)
|
||||
* Add command State to retrieve device state information (same data as teleperiod state and status 11 in slightly different JSON format)
|
||||
* Add optional login to Webserver AP mode (#1587, #1635)
|
||||
* Add command Sensor15 2 to start MHZ19(B) Zero Point Calibration (#1643)
|
||||
* Add support for Sonoff S31 Smart Socket with Power Consumption Detection (#1626)
|
||||
* Add command SetOption20 to allow update of Dimmer/Color/Ct without turning power on (#1719, #1741)
|
||||
* Add NTP sync time slot based on chip id (#1773)
|
||||
* Add cursor pointer to web button (#1836)
|
||||
*
|
||||
* 5.11.1 20180107
|
||||
* Fix Sonoff Pow command handling (#1542)
|
||||
*
|
||||
* 5.11.0 20180107
|
||||
|
||||
@ -75,6 +75,7 @@
|
||||
#define D_JSON_LOW "Low"
|
||||
#define D_JSON_MAC "Mac"
|
||||
#define D_JSON_MASK "Mask"
|
||||
#define D_JSON_MINIMAL "minimal"
|
||||
#define D_JSON_NO "No"
|
||||
#define D_JSON_NOISE "Noise"
|
||||
#define D_JSON_NONE "None"
|
||||
@ -117,6 +118,7 @@
|
||||
#define D_JSON_WIFI "Wifi"
|
||||
#define D_JSON_WRONG "Wrong"
|
||||
#define D_JSON_YESTERDAY "Yesterday"
|
||||
#define D_JSON_ZERO_POINT_CALIBRATION "Zero Point Calibration"
|
||||
|
||||
#define D_RSLT_ENERGY "ENERGY"
|
||||
#define D_RSLT_INFO "INFO"
|
||||
@ -165,11 +167,13 @@
|
||||
#define D_STATUS9_MARGIN "PTH"
|
||||
#define D_STATUS10_SENSOR "SNS"
|
||||
#define D_STATUS11_STATUS "STS"
|
||||
#define D_CMND_STATE "State"
|
||||
#define D_CMND_POWER "Power"
|
||||
#define D_CMND_POWERONSTATE "PowerOnState"
|
||||
#define D_CMND_PULSETIME "PulseTime"
|
||||
#define D_CMND_BLINKTIME "BlinkTime"
|
||||
#define D_CMND_BLINKCOUNT "BlinkCount"
|
||||
#define D_CMND_SENSOR "Sensor"
|
||||
#define D_CMND_SAVEDATA "SaveData"
|
||||
#define D_CMND_SETOPTION "SetOption"
|
||||
#define D_CMND_TEMPERATURE_RESOLUTION "TempRes"
|
||||
@ -235,7 +239,6 @@
|
||||
#define D_CMND_LEDSTATE "LedState"
|
||||
#define D_CMND_CFGDUMP "CfgDump"
|
||||
#define D_CMND_I2CSCAN "I2CScan"
|
||||
#define D_CMND_INA219MODE "Ina219Mode"
|
||||
#define D_CMND_EXCEPTION "Exception"
|
||||
|
||||
// Commands xdrv_01_light.ino
|
||||
@ -254,9 +257,20 @@
|
||||
|
||||
// Commands xdrv_02_irremote.ino
|
||||
#define D_CMND_IRSEND "IRSend"
|
||||
#define D_JSON_INVALID_JSON "Invalid JSON"
|
||||
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol not supported"
|
||||
#define D_JSON_IR_PROTOCOL "PROTOCOL"
|
||||
#define D_JSON_IR_BITS "BITS"
|
||||
#define D_JSON_IR_DATA "DATA"
|
||||
#define D_CMND_IRHVAC "IRHVAC"
|
||||
#define D_JSON_IRHVAC_VENDOR "VENDOR"
|
||||
#define D_JSON_IRHVAC_POWER "POWER"
|
||||
#define D_JSON_IRHVAC_MODE "MODE"
|
||||
#define D_JSON_IRHVAC_FANSPEED "FANSPEED"
|
||||
#define D_JSON_IRHVAC_TEMP "TEMP"
|
||||
#define D_JSON_IRRECEIVED "IrReceived"
|
||||
|
||||
// Commands xsns_03_energy.ino
|
||||
// Commands xdrv_03_energy.ino
|
||||
#define D_CMND_POWERLOW "PowerLow"
|
||||
#define D_CMND_POWERHIGH "PowerHigh"
|
||||
#define D_CMND_VOLTAGELOW "VoltageLow"
|
||||
@ -264,12 +278,12 @@
|
||||
#define D_CMND_CURRENTLOW "CurrentLow"
|
||||
#define D_CMND_CURRENTHIGH "CurrentHigh"
|
||||
#define D_CMND_ENERGYRESET "EnergyReset"
|
||||
#define D_CMND_HLWPCAL "HlwPcal"
|
||||
#define D_CMND_HLWPSET "HlwPset"
|
||||
#define D_CMND_HLWUCAL "HlwUcal"
|
||||
#define D_CMND_HLWUSET "HlwUset"
|
||||
#define D_CMND_HLWICAL "HlwIcal"
|
||||
#define D_CMND_HLWISET "HlwIset"
|
||||
#define D_CMND_POWERCAL "PowerCal"
|
||||
#define D_CMND_POWERSET "PowerSet"
|
||||
#define D_CMND_VOLTAGECAL "VoltageCal"
|
||||
#define D_CMND_VOLTAGESET "VoltageSet"
|
||||
#define D_CMND_CURRENTCAL "CurrentCal"
|
||||
#define D_CMND_CURRENTSET "CurrentSet"
|
||||
#define D_CMND_MAXPOWER "MaxPower"
|
||||
#define D_CMND_MAXPOWERHOLD "MaxPowerHold"
|
||||
#define D_CMND_MAXPOWERWINDOW "MaxPowerWindow"
|
||||
@ -359,7 +373,7 @@ const char kUnitNames[] PROGMEM =
|
||||
D_UNIT_MILLIAMPERE "|"
|
||||
D_UNIT_MILLISECOND "|"
|
||||
D_UNIT_MINUTE "|"
|
||||
D_UNIT_PPM "|"
|
||||
D_UNIT_PARTS_PER_MILLION "|"
|
||||
D_UNIT_PRESSURE "|"
|
||||
D_UNIT_SECOND "|"
|
||||
D_UNIT_SECTORS "|"
|
||||
@ -368,6 +382,7 @@ const char kUnitNames[] PROGMEM =
|
||||
D_UNIT_WATTHOUR ;
|
||||
|
||||
const char S_JSON_COMMAND_NVALUE_SPACE_UNIT[] PROGMEM = "{\"%s\":\"%d %s\"}";
|
||||
const char S_JSON_COMMAND_LVALUE_SPACE_UNIT[] PROGMEM = "{\"%s\":\"%lu %s\"}";
|
||||
const char S_JSON_COMMAND_SVALUE_SPACE_UNIT[] PROGMEM = "{\"%s\":\"%s %s\"}";
|
||||
const char S_JSON_COMMAND_NVALUE_UNIT[] PROGMEM = "{\"%s\":\"%d%s\"}";
|
||||
const char S_JSON_COMMAND_NVALUE_UNIT_NVALUE_UNIT[] PROGMEM = "{\"%s\":\"%d%s (%d%s)\"}";
|
||||
@ -376,13 +391,18 @@ const char S_JSON_COMMAND_NVALUE_SVALUE[] PROGMEM = "{\"%s\":\"%d (%s)
|
||||
const char S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE[] PROGMEM = "{\"%s\":\"%d (" D_JSON_ACTIVE " %d)\"}";
|
||||
|
||||
const char S_JSON_COMMAND_NVALUE[] PROGMEM = "{\"%s\":%d}";
|
||||
const char S_JSON_COMMAND_LVALUE[] PROGMEM = "{\"%s\":%lu}";
|
||||
const char S_JSON_COMMAND_SVALUE[] PROGMEM = "{\"%s\":\"%s\"}";
|
||||
const char S_JSON_COMMAND_XVALUE[] PROGMEM = "{\"%s\":%s}"; // %s must provide quotes on non-number
|
||||
|
||||
const char S_JSON_COMMAND_INDEX_NVALUE[] PROGMEM = "{\"%s%d\":%d}";
|
||||
const char S_JSON_COMMAND_INDEX_LVALUE[] PROGMEM = "{\"%s%d\":%lu}";
|
||||
const char S_JSON_COMMAND_INDEX_SVALUE[] PROGMEM = "{\"%s%d\":\"%s\"}";
|
||||
const char S_JSON_COMMAND_INDEX_SVALUE_SVALUE[] PROGMEM = "{\"%s%d\":\"%s%s\"}";
|
||||
|
||||
const char S_JSON_SENSOR_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":%d}";
|
||||
const char S_JSON_SENSOR_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":\"%s\"}";
|
||||
|
||||
const char JSON_SNS_TEMPHUM[] PROGMEM = "%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s}";
|
||||
|
||||
const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x";
|
||||
@ -422,13 +442,13 @@ static const char kMonthNames[] = D_MONTH3LIST;
|
||||
// webserver.ino
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s°%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
const char HTTP_SNS_PRESSURE[] PROGMEM = "%s{s}%s " D_PRESSURE "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "%s{s}%s " D_PRESSUREATSEALEVEL "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
const char HTTP_SNS_ANALOG[] PROGMEM = "%s{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
|
||||
#if defined(USE_MHZ19) || defined(USE_SENSEAIR)
|
||||
const char HTTP_SNS_CO2[] PROGMEM = "%s{s}%s " D_CO2 "{m}%d " D_UNIT_PPM "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
const char HTTP_SNS_CO2[] PROGMEM = "%s{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "."
|
||||
#define D_MONTH_DAY_SEPARATOR "."
|
||||
@ -149,6 +151,7 @@
|
||||
#define D_WEB_SERVER "Web-Server"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "WARNING This version does not support persistent settings"
|
||||
#define D_LEVEL_10 "level 1-0"
|
||||
#define D_LEVEL_01 "level 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Serielles logging deaktiviert"
|
||||
@ -334,19 +337,6 @@
|
||||
#define D_HUE_POST_ARGS "Hue POST args"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 Antwortpakete gesendet"
|
||||
|
||||
// xdrv_02_irremote.ino
|
||||
#define D_JSON_INVALID_JSON "ungültiger JSON"
|
||||
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protokoll nicht unterstützt"
|
||||
#define D_JSON_IR_PROTOCOL "PROTOKOLL"
|
||||
#define D_JSON_IR_BITS "BITS"
|
||||
#define D_JSON_IR_DATA "DATEN"
|
||||
#define D_JSON_IRHVAC_VENDOR "HERSTELLER"
|
||||
#define D_JSON_IRHVAC_POWER "STROM"
|
||||
#define D_JSON_IRHVAC_MODE "MODUS"
|
||||
#define D_JSON_IRHVAC_FANSPEED "LÜFTERGESCHWINDIGKEIT"
|
||||
#define D_JSON_IRHVAC_TEMP "TEMPERATUR"
|
||||
#define D_JSON_IRRECEIVED "IR empfangen"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
@ -364,7 +354,7 @@
|
||||
#define D_DOMOTICZ_AIRQUALITY "AirQuality"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Update timer"
|
||||
|
||||
// xsns_03_energy.ino
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energie heute"
|
||||
#define D_ENERGY_YESTERDAY "Energie gestern"
|
||||
#define D_ENERGY_TOTAL "Energie insgesamt"
|
||||
@ -385,8 +375,12 @@
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor hat ACK-Befehl nicht ausgeführt"
|
||||
#define D_SHT1X_FOUND "SHT1X gefunden"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "Particals"
|
||||
|
||||
// sonoff_template.h
|
||||
// Max string length is 8 characters including suffixes
|
||||
#define D_SENSOR_NONE "None"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
@ -412,6 +406,7 @@
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
@ -419,11 +414,14 @@
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "µs"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "min"
|
||||
#define D_UNIT_PPM "ppm"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "ppd"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sek"
|
||||
#define D_UNIT_SECTORS "Sektoren"
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "-"
|
||||
#define D_MONTH_DAY_SEPARATOR "-"
|
||||
@ -149,6 +151,7 @@
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "WARNING This version does not support persistent settings"
|
||||
#define D_LEVEL_10 "level 1-0"
|
||||
#define D_LEVEL_01 "level 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Serial logging disabled"
|
||||
@ -334,19 +337,6 @@
|
||||
#define D_HUE_POST_ARGS "Hue POST args"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 response packets sent"
|
||||
|
||||
// xdrv_02_irremote.ino
|
||||
#define D_JSON_INVALID_JSON "Invalid JSON"
|
||||
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol not supported"
|
||||
#define D_JSON_IR_PROTOCOL "PROTOCOL"
|
||||
#define D_JSON_IR_BITS "BITS"
|
||||
#define D_JSON_IR_DATA "DATA"
|
||||
#define D_JSON_IRHVAC_VENDOR "VENDOR"
|
||||
#define D_JSON_IRHVAC_POWER "POWER"
|
||||
#define D_JSON_IRHVAC_MODE "MODE"
|
||||
#define D_JSON_IRHVAC_FANSPEED "FANSPEED"
|
||||
#define D_JSON_IRHVAC_TEMP "TEMP"
|
||||
#define D_JSON_IRRECEIVED "IrReceived"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
@ -364,7 +354,7 @@
|
||||
#define D_DOMOTICZ_AIRQUALITY "AirQuality"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Update timer"
|
||||
|
||||
// xsns_03_energy.ino
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energy Today"
|
||||
#define D_ENERGY_YESTERDAY "Energy Yesterday"
|
||||
#define D_ENERGY_TOTAL "Energy Total"
|
||||
@ -385,8 +375,12 @@
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor did not ACK command"
|
||||
#define D_SHT1X_FOUND "SHT1X found"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "Particals"
|
||||
|
||||
// sonoff_template.h
|
||||
// Max string length is 8 characters including suffixes
|
||||
#define D_SENSOR_NONE "None"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
@ -412,6 +406,7 @@
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
@ -419,11 +414,14 @@
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "us"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "Min"
|
||||
#define D_UNIT_PPM "ppm"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "ppd"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sectors"
|
||||
|
||||
457
sonoff/language/es-AR.h
Normal file
457
sonoff/language/es-AR.h
Normal file
@ -0,0 +1,457 @@
|
||||
/*
|
||||
es-AR.h - localization for Spanish - Argentina for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Adrian Scillato
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LANGUAGE_ES_AR_H_
|
||||
#define _LANGUAGE_ES_AR_H_
|
||||
|
||||
/*************************** ATTENTION *******************************\
|
||||
*
|
||||
* Due to memory constraints only UTF-8 is supported.
|
||||
* To save code space keep text as short as possible.
|
||||
* Time and Date provided by SDK can not be localized (yet).
|
||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "-"
|
||||
#define D_MONTH_DAY_SEPARATOR "-"
|
||||
#define D_DATE_TIME_SEPARATOR "T"
|
||||
#define D_HOUR_MINUTE_SEPARATOR ":"
|
||||
#define D_MINUTE_SECOND_SEPARATOR ":"
|
||||
|
||||
#define D_DAY3LIST "DomLunMarMieJueVieSab"
|
||||
#define D_MONTH3LIST "EneFebMarAbrMayJunJulAgoSepOctNovDic"
|
||||
|
||||
// Non JSON decimal separator
|
||||
#define D_DECIMAL_SEPARATOR ","
|
||||
|
||||
// Common
|
||||
#define D_ADMIN "Admin"
|
||||
#define D_AIR_QUALITY "Calidad del Aire"
|
||||
#define D_AP "AP" // Access Point
|
||||
#define D_AS "como"
|
||||
#define D_AUTO "AUTO"
|
||||
#define D_BLINK "Blink"
|
||||
#define D_BLINKOFF "BlinkOff"
|
||||
#define D_BOOT_COUNT "Conteo Reinicios"
|
||||
#define D_BRIGHTLIGHT "Brillante"
|
||||
#define D_BUTTON "Botón"
|
||||
#define D_BY "por" // Written by me
|
||||
#define D_BYTES "Bytes"
|
||||
#define D_CELSIUS "Celsius"
|
||||
#define D_CO2 "CO2"
|
||||
#define D_CODE "código" // Button code
|
||||
#define D_COLDLIGHT "Fría"
|
||||
#define D_COMMAND "Comando"
|
||||
#define D_CONNECTED "Conectado"
|
||||
#define D_COUNT "Conteo"
|
||||
#define D_COUNTER "Contador"
|
||||
#define D_CURRENT "Corriente" // As in Voltage and Current
|
||||
#define D_DATA "Datos"
|
||||
#define D_DARKLIGHT "Oscura"
|
||||
#define D_DEBUG "Debug"
|
||||
#define D_DISABLED "Deshabilitado"
|
||||
#define D_DNS_SERVER "DNS Server"
|
||||
#define D_DONE "Listo"
|
||||
#define D_DST_TIME "DST"
|
||||
#define D_EMULATION "Emulación"
|
||||
#define D_ENABLED "Habilitado"
|
||||
#define D_ERASE "Borrar"
|
||||
#define D_ERROR "Error"
|
||||
#define D_FAHRENHEIT "Fahrenheit"
|
||||
#define D_FAILED "Falló"
|
||||
#define D_FALLBACK "Fallback"
|
||||
#define D_FALLBACK_TOPIC "FallbackTopic"
|
||||
#define D_FALSE "Falso"
|
||||
#define D_FILE "Archivo"
|
||||
#define D_FREE_MEMORY "Memoria Libre"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Grupo"
|
||||
#define D_HOST "Host"
|
||||
#define D_HOSTNAME "Hostname"
|
||||
#define D_HUMIDITY "Humedad"
|
||||
#define D_ILLUMINANCE "Luminancia"
|
||||
#define D_IMMEDIATE "inmediato" // Button immediate
|
||||
#define D_INDEX "Índice"
|
||||
#define D_INFO "Información"
|
||||
#define D_INITIALIZED "Inicializado"
|
||||
#define D_IP_ADDRESS "Dirección IP"
|
||||
#define D_LIGHT "Luz"
|
||||
#define D_LWT "LWT"
|
||||
#define D_MODULE "Módulo"
|
||||
#define D_MQTT "MQTT"
|
||||
#define D_MULTI_PRESS "multi-press"
|
||||
#define D_NOISE "Ruido"
|
||||
#define D_NONE "Ninguno"
|
||||
#define D_OFF "Apagado"
|
||||
#define D_OFFLINE "Offline"
|
||||
#define D_OK "Ok"
|
||||
#define D_ON "Encendido"
|
||||
#define D_ONLINE "Online"
|
||||
#define D_PASSWORD "Clave"
|
||||
#define D_PORT "Puerto"
|
||||
#define D_POWER_FACTOR "Factor de Potencia"
|
||||
#define D_POWERUSAGE "Potencia"
|
||||
#define D_PRESSURE "Presión"
|
||||
#define D_PRESSUREATSEALEVEL "Presión al nivel del mar"
|
||||
#define D_PROGRAM_FLASH_SIZE "Tamaño de Flash de Programa"
|
||||
#define D_PROGRAM_SIZE "Tamaño Programa"
|
||||
#define D_PROJECT "Proyecto"
|
||||
#define D_RECEIVED "Recibido"
|
||||
#define D_RESTART "Reinicio"
|
||||
#define D_RESTARTING "Reiniciando"
|
||||
#define D_RESTART_REASON "Causa Reinicio"
|
||||
#define D_RESTORE "Restauración"
|
||||
#define D_RETAINED "Grabado"
|
||||
#define D_SAVE "Grabar"
|
||||
#define D_SENSOR "Sensor"
|
||||
#define D_SSID "SSId"
|
||||
#define D_START "Iniciar"
|
||||
#define D_STD_TIME "STD"
|
||||
#define D_STOP "Detener"
|
||||
#define D_SUBNET_MASK "Máscara Subred"
|
||||
#define D_SUBSCRIBE_TO "Suscribir a"
|
||||
#define D_SUCCESSFUL "Exitosa"
|
||||
#define D_TEMPERATURE "Temperatura"
|
||||
#define D_TO "a"
|
||||
#define D_TOGGLE "Conmutar"
|
||||
#define D_TOPIC "Topic"
|
||||
#define D_TRANSMIT "Transmitir"
|
||||
#define D_TRUE "Verdadero"
|
||||
#define D_UPGRADE "Actualización"
|
||||
#define D_UPLOAD "Carga"
|
||||
#define D_UPTIME "Tiempo Encendido"
|
||||
#define D_USER "Usuario"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_LEVEL "Nivel UV"
|
||||
#define D_VERSION "Versión"
|
||||
#define D_VOLTAGE "Tensión"
|
||||
#define D_WARMLIGHT "Cálida"
|
||||
#define D_WEB_SERVER "Servidor Web"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "Precaución, esta versión no salva los cambios"
|
||||
#define D_LEVEL_10 "level 1-0"
|
||||
#define D_LEVEL_01 "level 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Log serial deshabilitado"
|
||||
#define D_SYSLOG_LOGGING_REENABLED "Syslog re-habilitado"
|
||||
|
||||
#define D_SET_BAUDRATE_TO "Baudrate a"
|
||||
#define D_RECEIVED_TOPIC "Topic Recibido"
|
||||
#define D_DATA_SIZE "Tamaño de Datos"
|
||||
#define D_ANALOG_INPUT "Entrada Analógica"
|
||||
|
||||
#define D_FINGERPRINT "Verificar TLS fingerprint..."
|
||||
#define D_TLS_CONNECT_FAILED_TO "Falló Conección TLS a"
|
||||
#define D_RETRY_IN "Reintentando"
|
||||
#define D_VERIFIED "Verificado"
|
||||
#define D_INSECURE "Conección insegura por Fingerprint no válido"
|
||||
#define D_CONNECT_FAILED_TO "Falló Conección a"
|
||||
|
||||
// support.ino
|
||||
#define D_OSWATCH "osWatch"
|
||||
#define D_BLOCKED_LOOP "Ciclo Bloqueado"
|
||||
#define D_WPS_FAILED_WITH_STATUS "WPSconfig FALLÓ con estado"
|
||||
#define D_ACTIVE_FOR_3_MINUTES "activo por 3 minutos"
|
||||
#define D_FAILED_TO_START "falló inicio"
|
||||
#define D_PATCH_ISSUE_2186 "Patch issue 2186"
|
||||
#define D_CONNECTING_TO_AP "Connectando a AP"
|
||||
#define D_IN_MODE "en modo"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Falló Conección, Dirección IP no recibida"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "Falló Conección, AP no pudo ser contactado"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "Falló Conección, clave de AP incorrecta"
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "Falló Conección, timeout de AP"
|
||||
#define D_ATTEMPTING_CONNECTION "Intentando conectar..."
|
||||
#define D_CHECKING_CONNECTION "Probando conección..."
|
||||
#define D_QUERY_DONE "Consulta lista. Servicio MQTT encontrado"
|
||||
#define D_MQTT_SERVICE_FOUND "Servicio MQTT encontrado en"
|
||||
#define D_FOUND_AT "encontrado en"
|
||||
#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host no encontrado"
|
||||
|
||||
// settings.ino
|
||||
#define D_SAVED_TO_FLASH_AT "Grabado a la flash en"
|
||||
#define D_LOADED_FROM_FLASH_AT "Cargado desde flash en"
|
||||
#define D_USE_DEFAULTS "Usar valores por defecto"
|
||||
#define D_ERASED_SECTOR "Sector borrado"
|
||||
|
||||
// webserver.ino
|
||||
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "firmware MÍNIMO - actualice por favor"
|
||||
#define D_WEBSERVER_ACTIVE_ON "Servidor web activo en"
|
||||
#define D_WITH_IP_ADDRESS "con dirección IP"
|
||||
#define D_WEBSERVER_STOPPED "Servidor web detenido"
|
||||
#define D_FILE_NOT_FOUND "Archivo No Encontrado"
|
||||
#define D_REDIRECTED "Redireccinado al portal captivo"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager como AccessPoint y Estación"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager como AccessPoint"
|
||||
#define D_TRYING_TO_CONNECT "Intentado conectar dispositivo a la red"
|
||||
|
||||
#define D_RESTART_IN "Reinicio en"
|
||||
#define D_SECONDS "segundos"
|
||||
#define D_DEVICE_WILL_RESTART "El dispositivo se reiniciará en pocos segundos"
|
||||
#define D_BUTTON_TOGGLE "Alternar ON/OFF"
|
||||
#define D_CONFIGURATION "Configuración"
|
||||
#define D_INFORMATION "Información"
|
||||
#define D_FIRMWARE_UPGRADE "Actualización Firmware"
|
||||
#define D_CONSOLE "Consola"
|
||||
#define D_CONFIRM_RESTART "Confirmar Reinicio"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configuración del Módulo"
|
||||
#define D_CONFIGURE_WIFI "Configuración WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configuración MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configuración Domoticz"
|
||||
#define D_CONFIGURE_LOGGING "Configuración Logging"
|
||||
#define D_CONFIGURE_OTHER "Configuración Extra"
|
||||
#define D_CONFIRM_RESET_CONFIGURATION "Confirmar Reset Configuración"
|
||||
#define D_RESET_CONFIGURATION "Reset de Configuración"
|
||||
#define D_BACKUP_CONFIGURATION "Backup de Configuración"
|
||||
#define D_RESTORE_CONFIGURATION "Restaurar Configuración"
|
||||
#define D_MAIN_MENU "Menú Principal"
|
||||
|
||||
#define D_MODULE_PARAMETERS "Parámetros del módulo"
|
||||
#define D_MODULE_TYPE "Tipo módulo"
|
||||
#define D_GPIO "GPIO"
|
||||
#define D_SERIAL_IN "Serial In"
|
||||
#define D_SERIAL_OUT "Serial Out"
|
||||
|
||||
#define D_WIFI_PARAMETERS "Parámetros Wifi"
|
||||
#define D_SCAN_FOR_WIFI_NETWORKS "Buscar redes wifi"
|
||||
#define D_SCAN_DONE "Busqueda finalizada"
|
||||
#define D_NO_NETWORKS_FOUND "Ninguna red encontrada"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "Recargar página para buscar nuevamente"
|
||||
#define D_DUPLICATE_ACCESSPOINT "AccessPoint duplicado"
|
||||
#define D_SKIPPING_LOW_QUALITY "Ignorado debido a baja calidad"
|
||||
#define D_RSSI "RSSI"
|
||||
#define D_WEP "WEP"
|
||||
#define D_WPA_PSK "WPA PSK"
|
||||
#define D_WPA2_PSK "WPA2 PSK"
|
||||
#define D_AP1_SSID "SSId AP1"
|
||||
#define D_AP1_PASSWORD "Clave AP1"
|
||||
#define D_AP2_SSID "SSId AP2"
|
||||
#define D_AP2_PASSWORD "Clave AP2"
|
||||
|
||||
#define D_MQTT_PARAMETERS "Parámetros MQTT"
|
||||
#define D_CLIENT "Cliente"
|
||||
#define D_FULL_TOPIC "Full Topic"
|
||||
|
||||
#define D_LOGGING_PARAMETERS "Parámetros Logging"
|
||||
#define D_SERIAL_LOG_LEVEL "Nivel de log Serial"
|
||||
#define D_WEB_LOG_LEVEL "Nivel de log Web"
|
||||
#define D_SYS_LOG_LEVEL "Nivel de Syslog"
|
||||
#define D_MORE_DEBUG "Mas Debug"
|
||||
#define D_SYSLOG_HOST "Host del Syslog"
|
||||
#define D_SYSLOG_PORT "Puerto del Syslog"
|
||||
#define D_TELEMETRY_PERIOD "Período de Telemetría"
|
||||
|
||||
#define D_OTHER_PARAMETERS "Otros parámetros"
|
||||
#define D_WEB_ADMIN_PASSWORD "Clave Administrador Web"
|
||||
#define D_MQTT_ENABLE "Habilitar MQTT"
|
||||
#define D_FRIENDLY_NAME "Nombre Amigable"
|
||||
#define D_BELKIN_WEMO "Belkin WeMo"
|
||||
#define D_HUE_BRIDGE "Hue Bridge"
|
||||
#define D_SINGLE_DEVICE "dispositivo simple"
|
||||
#define D_MULTI_DEVICE "dispositivo múltiple"
|
||||
|
||||
#define D_SAVE_CONFIGURATION "Grabar configuración"
|
||||
#define D_CONFIGURATION_SAVED "Configuración grabada"
|
||||
#define D_CONFIGURATION_RESET "Configuración restablecida"
|
||||
|
||||
#define D_PROGRAM_VERSION "Versión del Programa"
|
||||
#define D_BUILD_DATE_AND_TIME "Fecha y Hora de la Compilación"
|
||||
#define D_CORE_AND_SDK_VERSION "Versión Core/SDK"
|
||||
#define D_FLASH_WRITE_COUNT "Contador de escritura en Flash"
|
||||
#define D_MAC_ADDRESS "Dirección MAC"
|
||||
#define D_MQTT_HOST "Host MQTT"
|
||||
#define D_MQTT_PORT "Puerto MQTT"
|
||||
#define D_MQTT_CLIENT "Cliente MQTT"
|
||||
#define D_MQTT_USER "Usuario MQTT"
|
||||
#define D_MQTT_TOPIC "Topic MQTT"
|
||||
#define D_MQTT_GROUP_TOPIC "Group Topic MQTT"
|
||||
#define D_MQTT_FULL_TOPIC "Full Topic MQTT"
|
||||
#define D_MDNS_DISCOVERY "mDNS Discovery"
|
||||
#define D_MDNS_ADVERTISE "mDNS Advertise"
|
||||
#define D_ESP_CHIP_ID "ESP Chip Id"
|
||||
#define D_FLASH_CHIP_ID "Flash Chip Id"
|
||||
#define D_FLASH_CHIP_SIZE "Tamaño Flash"
|
||||
#define D_FREE_PROGRAM_SPACE "Memoria de Programa Libre"
|
||||
|
||||
#define D_UPGRADE_BY_WEBSERVER "Actualizar por servidor web"
|
||||
#define D_OTA_URL "OTA Url"
|
||||
#define D_START_UPGRADE "Comenzar actualización"
|
||||
#define D_UPGRADE_BY_FILE_UPLOAD "Actualizar cargando archivo bin"
|
||||
#define D_UPLOAD_STARTED "Cargando archivo"
|
||||
#define D_UPGRADE_STARTED "Actualización iniciada"
|
||||
#define D_UPLOAD_DONE "Carga finalizada"
|
||||
#define D_UPLOAD_ERR_1 "Ningún archivo seleccionado"
|
||||
#define D_UPLOAD_ERR_2 "Espacio insuficiente"
|
||||
#define D_UPLOAD_ERR_3 "Magic byte no corresponde a 0xE9"
|
||||
#define D_UPLOAD_ERR_4 "El tamaño de la memoria de programa es mayor que la de la flash"
|
||||
#define D_UPLOAD_ERR_5 "Error de comparación del buffer de carga"
|
||||
#define D_UPLOAD_ERR_6 "Carga fallida. Habilitar logging 3"
|
||||
#define D_UPLOAD_ERR_7 "Carga cancelada"
|
||||
#define D_UPLOAD_ERR_8 "Archivo no válido"
|
||||
#define D_UPLOAD_ERR_9 "Archivo muy grande"
|
||||
#define D_UPLOAD_ERROR_CODE "Código de error de carga"
|
||||
|
||||
#define D_ENTER_COMMAND "Ingresar comando"
|
||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 si desea respuesta"
|
||||
#define D_NEED_USER_AND_PASSWORD "Se necesita user=<username>&password=<password>"
|
||||
|
||||
// xdrv_wemohue.ino
|
||||
#define D_MULTICAST_DISABLED "Multicast deshabilitado"
|
||||
#define D_MULTICAST_REJOINED "Multicast (re)conectado"
|
||||
#define D_MULTICAST_JOIN_FAILED "Conección Multicast fallida"
|
||||
#define D_FAILED_TO_SEND_RESPONSE "Falla al enviar respuesta"
|
||||
|
||||
#define D_WEMO "WeMo"
|
||||
#define D_WEMO_BASIC_EVENT "Evento base de WeMo"
|
||||
#define D_WEMO_EVENT_SERVICE "Evento de servicio de WeMo"
|
||||
#define D_WEMO_META_SERVICE "Meta Servicio de WeMo"
|
||||
#define D_WEMO_SETUP "Configuración de WeMo"
|
||||
#define D_RESPONSE_SENT "Respuesta enviada"
|
||||
|
||||
#define D_HUE "Hue"
|
||||
#define D_HUE_BRIDGE_SETUP "Configuración Hue"
|
||||
#define D_HUE_API_NOT_IMPLEMENTED "API de Hue no implementada"
|
||||
#define D_HUE_API "Hue API"
|
||||
#define D_HUE_POST_ARGS "Hue POST args"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 paquetes de respuesta enviados"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Parámetros Domoticz"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
#define D_DOMOTICZ_KEY_IDX "Key idx"
|
||||
#define D_DOMOTICZ_SWITCH_IDX "Switch idx"
|
||||
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
|
||||
#define D_DOMOTICZ_TEMP "Temp"
|
||||
#define D_DOMOTICZ_TEMP_HUM "Temp,Hum"
|
||||
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro"
|
||||
#define D_DOMOTICZ_POWER_ENERGY "Potencia,Energía"
|
||||
#define D_DOMOTICZ_ILLUMINANCE "Luminancia"
|
||||
#define D_DOMOTICZ_COUNT "Contador"
|
||||
#define D_DOMOTICZ_VOLTAGE "Voltaje"
|
||||
#define D_DOMOTICZ_CURRENT "Corriente"
|
||||
#define D_DOMOTICZ_AIRQUALITY "Calidad del Aire"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Intervalo de refresco"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energía Hoy"
|
||||
#define D_ENERGY_YESTERDAY "Energía Ayer"
|
||||
#define D_ENERGY_TOTAL "Energía Total"
|
||||
|
||||
// xsns_05_ds18b20.ino
|
||||
#define D_SENSOR_BUSY "Sensor ocupado"
|
||||
#define D_SENSOR_CRC_ERROR "Error CRC del Sensor"
|
||||
#define D_SENSORS_FOUND "Sensores encontrados"
|
||||
|
||||
// xsns_06_dht.ino
|
||||
#define D_TIMEOUT_WAITING_FOR "Espera de timeout por"
|
||||
#define D_START_SIGNAL_LOW "iniciar señal baja"
|
||||
#define D_START_SIGNAL_HIGH "iniciar señal alta"
|
||||
#define D_PULSE "pulso"
|
||||
#define D_CHECKSUM_FAILURE "Checksum fallido"
|
||||
|
||||
// xsns_07_sht1x.ino
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor no ha enviado el comando ACK"
|
||||
#define D_SHT1X_FOUND "SHT1X encontrado"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "Partículas"
|
||||
|
||||
// sonoff_template.h
|
||||
#define D_SENSOR_NONE "Ninguno"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
#define D_SENSOR_SI7021 "SI7021"
|
||||
#define D_SENSOR_DS18X20 "DS18x20"
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_IRSEND "IR TX"
|
||||
#define D_SENSOR_SWITCH "Llave" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Botón" // Suffix "1"
|
||||
#define D_SENSOR_RELAY "Relé" // Suffix "1i"
|
||||
#define D_SENSOR_LED "Led" // Suffix "1i"
|
||||
#define D_SENSOR_PWM "PWM" // Suffix "1"
|
||||
#define D_SENSOR_COUNTER "Counter" // Suffix "1"
|
||||
#define D_SENSOR_IRRECV "IR RX"
|
||||
#define D_SENSOR_MHZ_RX "MHZ Rx"
|
||||
#define D_SENSOR_MHZ_TX "MHZ Tx"
|
||||
#define D_SENSOR_PZEM_RX "PZEM Rx"
|
||||
#define D_SENSOR_PZEM_TX "PZEM Tx"
|
||||
#define D_SENSOR_SAIR_RX "SAir Rx"
|
||||
#define D_SENSOR_SAIR_TX "SAir Tx"
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_HOUR "Hr"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "us"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "Min"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "ppd"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "seg"
|
||||
#define D_UNIT_SECTORS "sectores"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
||||
// Log message prefix
|
||||
#define D_LOG_APPLICATION "APP: " // Application
|
||||
#define D_LOG_BRIDGE "BRG: " // Bridge
|
||||
#define D_LOG_CONFIG "CFG: " // Settings
|
||||
#define D_LOG_COMMAND "CMD: " // Command
|
||||
#define D_LOG_DEBUG "DBG: " // Debug
|
||||
#define D_LOG_DHT "DHT: " // DHT sensor
|
||||
#define D_LOG_DOMOTICZ "DOM: " // Domoticz
|
||||
#define D_LOG_DSB "DSB: " // DS18xB20 sensor
|
||||
#define D_LOG_HTTP "HTP: " // HTTP webserver
|
||||
#define D_LOG_I2C "I2C: " // I2C
|
||||
#define D_LOG_IRR "IRR: " // Infra Red Received
|
||||
#define D_LOG_LOG "LOG: " // Logging
|
||||
#define D_LOG_MODULE "MOD: " // Module
|
||||
#define D_LOG_MDNS "DNS: " // mDNS
|
||||
#define D_LOG_MQTT "MQT: " // MQTT
|
||||
#define D_LOG_OTHER "OTH: " // Other
|
||||
#define D_LOG_RESULT "RSL: " // Result
|
||||
#define D_LOG_RFR "RFR: " // RF Received
|
||||
#define D_LOG_SERIAL "SER: " // Serial
|
||||
#define D_LOG_SHT1 "SHT: " // SHT1x sensor
|
||||
#define D_LOG_UPLOAD "UPL: " // Upload
|
||||
#define D_LOG_UPNP "UPP: " // UPnP
|
||||
#define D_LOG_WIFI "WIF: " // Wifi
|
||||
|
||||
#endif // _LANGUAGE_ES_AR_H_
|
||||
457
sonoff/language/fr-FR.h
Normal file
457
sonoff/language/fr-FR.h
Normal file
@ -0,0 +1,457 @@
|
||||
/*
|
||||
fr-FR.h - localization for French - France for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Olivier Francais
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LANGUAGE_FR_FR_H_
|
||||
#define _LANGUAGE_FR_FR_H_
|
||||
|
||||
/*************************** ATTENTION *******************************\
|
||||
*
|
||||
* Due to memory constraints only UTF-8 is supported.
|
||||
* To save code space keep text as short as possible.
|
||||
* Time and Date provided by SDK can not be localized (yet).
|
||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "-"
|
||||
#define D_MONTH_DAY_SEPARATOR "-"
|
||||
#define D_DATE_TIME_SEPARATOR "T"
|
||||
#define D_HOUR_MINUTE_SEPARATOR ":"
|
||||
#define D_MINUTE_SECOND_SEPARATOR ":"
|
||||
|
||||
#define D_DAY3LIST "DimLunMarMerJeuVenSam"
|
||||
#define D_MONTH3LIST "JanFevMarAvrMaiJunJulAutSepOctNovDec"
|
||||
|
||||
// Non JSON decimal separator
|
||||
#define D_DECIMAL_SEPARATOR ","
|
||||
|
||||
// Common
|
||||
#define D_ADMIN "Admin"
|
||||
#define D_AIR_QUALITY "Qualité de l'Air"
|
||||
#define D_AP "AP" // Access Point
|
||||
#define D_AS "comme"
|
||||
#define D_AUTO "AUTO"
|
||||
#define D_BLINK "Blink"
|
||||
#define D_BLINKOFF "BlinkOff"
|
||||
#define D_BOOT_COUNT "Nombre de boot"
|
||||
#define D_BRIGHTLIGHT "Luminosité"
|
||||
#define D_BUTTON "Boutton"
|
||||
#define D_BY "par" // Written by me
|
||||
#define D_BYTES "Bytes"
|
||||
#define D_CELSIUS "Celsius"
|
||||
#define D_CO2 "Dioxyde de carbone"
|
||||
#define D_CODE "code" // Button code
|
||||
#define D_COLDLIGHT "Froid"
|
||||
#define D_COMMAND "Commande"
|
||||
#define D_CONNECTED "Connecté"
|
||||
#define D_COUNT "Compte"
|
||||
#define D_COUNTER "Compteur"
|
||||
#define D_CURRENT "Courrant" // As in Voltage and Current
|
||||
#define D_DATA "Data"
|
||||
#define D_DARKLIGHT "Sombre"
|
||||
#define D_DEBUG "Debug"
|
||||
#define D_DISABLED "Désactivé"
|
||||
#define D_DNS_SERVER "Serveur DNS"
|
||||
#define D_DONE "Fait"
|
||||
#define D_DST_TIME "DST"
|
||||
#define D_EMULATION "Emulation"
|
||||
#define D_ENABLED "Activé"
|
||||
#define D_ERASE "Effacer"
|
||||
#define D_ERROR "Erreur"
|
||||
#define D_FAHRENHEIT "Fahrenheit"
|
||||
#define D_FAILED "Echoué"
|
||||
#define D_FALLBACK "Fallback"
|
||||
#define D_FALLBACK_TOPIC "Fallback Topic"
|
||||
#define D_FALSE "Faux"
|
||||
#define D_FILE "Fichier"
|
||||
#define D_FREE_MEMORY "Memoire libre"
|
||||
#define D_GAS "Gaz"
|
||||
#define D_GATEWAY "Passerelle"
|
||||
#define D_GROUP "Groupe"
|
||||
#define D_HOST "Host"
|
||||
#define D_HOSTNAME "Hostname"
|
||||
#define D_HUMIDITY "Humidité"
|
||||
#define D_ILLUMINANCE "Éclairement"
|
||||
#define D_IMMEDIATE "immediat" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INFO "Info"
|
||||
#define D_INITIALIZED "Initialisé"
|
||||
#define D_IP_ADDRESS "Adresse IP"
|
||||
#define D_LIGHT "Lumière"
|
||||
#define D_LWT "LWT"
|
||||
#define D_MODULE "Module"
|
||||
#define D_MQTT "MQTT"
|
||||
#define D_MULTI_PRESS "multi-pression"
|
||||
#define D_NOISE "Bruit"
|
||||
#define D_NONE "None"
|
||||
#define D_OFF "Off"
|
||||
#define D_OFFLINE "Déconnecté"
|
||||
#define D_OK "Ok"
|
||||
#define D_ON "On"
|
||||
#define D_ONLINE "Connecté"
|
||||
#define D_PASSWORD "Mot de passe"
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Facteur de puissance"
|
||||
#define D_POWERUSAGE "Puissance"
|
||||
#define D_PRESSURE "Pression"
|
||||
#define D_PRESSUREATSEALEVEL "PressionMer"
|
||||
#define D_PROGRAM_FLASH_SIZE "Taille Flash Programme"
|
||||
#define D_PROGRAM_SIZE "Taille programme"
|
||||
#define D_PROJECT "Projet"
|
||||
#define D_RECEIVED "Reçu"
|
||||
#define D_RESTART "Redémarrage"
|
||||
#define D_RESTARTING "Redémarrage"
|
||||
#define D_RESTART_REASON "Raison redémarrage"
|
||||
#define D_RESTORE "restorer"
|
||||
#define D_RETAINED "retenu"
|
||||
#define D_SAVE "Enregister"
|
||||
#define D_SENSOR "Capteur"
|
||||
#define D_SSID "SSID"
|
||||
#define D_START "Start"
|
||||
#define D_STD_TIME "STD"
|
||||
#define D_STOP "Stop"
|
||||
#define D_SUBNET_MASK "Masque sous réseau"
|
||||
#define D_SUBSCRIBE_TO "Souscrire à"
|
||||
#define D_SUCCESSFUL "Réussi"
|
||||
#define D_TEMPERATURE "Temperature"
|
||||
#define D_TO "à"
|
||||
#define D_TOGGLE "Bascule"
|
||||
#define D_TOPIC "Topic"
|
||||
#define D_TRANSMIT "Transmettre"
|
||||
#define D_TRUE "Vrai"
|
||||
#define D_UPGRADE "upgrade"
|
||||
#define D_UPLOAD "Upload"
|
||||
#define D_UPTIME "Uptime"
|
||||
#define D_USER "Utilisateur"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_LEVEL "Niveau UV"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Voltage"
|
||||
#define D_WARMLIGHT "Chaud"
|
||||
#define D_WEB_SERVER "Serveur web"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "ATTENTION Cette version ne supporte pas les réglages persistants"
|
||||
#define D_LEVEL_10 "level 1-0"
|
||||
#define D_LEVEL_01 "level 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Journalisation série désactivé"
|
||||
#define D_SYSLOG_LOGGING_REENABLED "Jounalisation syslog réactivé"
|
||||
|
||||
#define D_SET_BAUDRATE_TO "Definir baudrate à"
|
||||
#define D_RECEIVED_TOPIC "Topic reçu"
|
||||
#define D_DATA_SIZE "Taille données"
|
||||
#define D_ANALOG_INPUT "Analogique"
|
||||
|
||||
#define D_FINGERPRINT "Verification empreinte TLS ..."
|
||||
#define D_TLS_CONNECT_FAILED_TO "Echec de connexion TLS à"
|
||||
#define D_RETRY_IN "Nouvelle tentative dans"
|
||||
#define D_VERIFIED "Verifié"
|
||||
#define D_INSECURE "Connexion non sécurisée car empreinte non vérifée"
|
||||
#define D_CONNECT_FAILED_TO "Echec de connexion à"
|
||||
|
||||
// support.ino
|
||||
#define D_OSWATCH "osWatch"
|
||||
#define D_BLOCKED_LOOP "Boucle bloquée"
|
||||
#define D_WPS_FAILED_WITH_STATUS "WPSconfig ECHOUÉ avec status"
|
||||
#define D_ACTIVE_FOR_3_MINUTES "actif pour 3 minutes"
|
||||
#define D_FAILED_TO_START "Echec de démarrage"
|
||||
#define D_PATCH_ISSUE_2186 "Patch issue 2186"
|
||||
#define D_CONNECTING_TO_AP "Connexion à l'AP"
|
||||
#define D_IN_MODE "en mode"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Echec de connexion car aucune adresse IP n'a été reçue"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "Echec de connexion car l'AP ne peut-être contacté"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "Echec de connexion car le mot de passe de l'AP est incorrect"
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "Echec de connexion avec l'AP, expiré"
|
||||
#define D_ATTEMPTING_CONNECTION "Tentative de connexion..."
|
||||
#define D_CHECKING_CONNECTION "Verification connexion..."
|
||||
#define D_QUERY_DONE "Requête terminé. Services MQTT trouvés"
|
||||
#define D_MQTT_SERVICE_FOUND "Service MQTT trouvé sur"
|
||||
#define D_FOUND_AT "trouvé à"
|
||||
#define D_SYSLOG_HOST_NOT_FOUND "Host syslog introuvable"
|
||||
|
||||
// settings.ino
|
||||
#define D_SAVED_TO_FLASH_AT "Enregistré dans la flash à"
|
||||
#define D_LOADED_FROM_FLASH_AT "Chargé de la flash à"
|
||||
#define D_USE_DEFAULTS "Utiliser par défaut"
|
||||
#define D_ERASED_SECTOR "Secteur effacé"
|
||||
|
||||
// webserver.ino
|
||||
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MINIMAL - merci de mettre à jour"
|
||||
#define D_WEBSERVER_ACTIVE_ON "Serveur web actif sur"
|
||||
#define D_WITH_IP_ADDRESS "avec l'adresse IP"
|
||||
#define D_WEBSERVER_STOPPED "Serveur web éteint"
|
||||
#define D_FILE_NOT_FOUND "Fichier introuvable"
|
||||
#define D_REDIRECTED "Redirection sur le portail captif"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager defini AccessPoint et garde station"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager defini AccessPoint"
|
||||
#define D_TRYING_TO_CONNECT "Tentative de connexion du module au réseau"
|
||||
|
||||
#define D_RESTART_IN "Redémarrage dans"
|
||||
#define D_SECONDS "secondes"
|
||||
#define D_DEVICE_WILL_RESTART "Le module va redémarrer dans quelques secondes"
|
||||
#define D_BUTTON_TOGGLE "on/off"
|
||||
#define D_CONFIGURATION "Configuration"
|
||||
#define D_INFORMATION "Information"
|
||||
#define D_FIRMWARE_UPGRADE "Mise à jour Firmware"
|
||||
#define D_CONSOLE "Console"
|
||||
#define D_CONFIRM_RESTART "Confirmer redémarrage"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configuration Module"
|
||||
#define D_CONFIGURE_WIFI "Configuration WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configuration MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configuration Domoticz"
|
||||
#define D_CONFIGURE_LOGGING "Configuration Logging"
|
||||
#define D_CONFIGURE_OTHER "Autre configuration"
|
||||
#define D_CONFIRM_RESET_CONFIGURATION "Confirmer réinitialisation configuration"
|
||||
#define D_RESET_CONFIGURATION "Réinitialisation Configuration"
|
||||
#define D_BACKUP_CONFIGURATION "Sauvegarde Configuration"
|
||||
#define D_RESTORE_CONFIGURATION "Restauration Configuration"
|
||||
#define D_MAIN_MENU "Menu principal"
|
||||
|
||||
#define D_MODULE_PARAMETERS "Paramètres module"
|
||||
#define D_MODULE_TYPE "Type module"
|
||||
#define D_GPIO "GPIO"
|
||||
#define D_SERIAL_IN "Serial In"
|
||||
#define D_SERIAL_OUT "Serial Out"
|
||||
|
||||
#define D_WIFI_PARAMETERS "Paramètres Wifi"
|
||||
#define D_SCAN_FOR_WIFI_NETWORKS "Scan des réseaux wifi"
|
||||
#define D_SCAN_DONE "Scan terminé"
|
||||
#define D_NO_NETWORKS_FOUND "Aucun réseau trouvé"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "Rafraichir pour scanner à nouveau"
|
||||
#define D_DUPLICATE_ACCESSPOINT "AccessPoint dupliqué"
|
||||
#define D_SKIPPING_LOW_QUALITY "Passe car mauvaise qualité"
|
||||
#define D_RSSI "RSSI"
|
||||
#define D_WEP "WEP"
|
||||
#define D_WPA_PSK "WPA PSK"
|
||||
#define D_WPA2_PSK "WPA2 PSK"
|
||||
#define D_AP1_SSID "AP1 SSID"
|
||||
#define D_AP1_PASSWORD "Mot de passe AP1"
|
||||
#define D_AP2_SSID "AP2 SSId"
|
||||
#define D_AP2_PASSWORD "Mot de passe AP2"
|
||||
|
||||
#define D_MQTT_PARAMETERS "Paramètres MQTT"
|
||||
#define D_CLIENT "Client"
|
||||
#define D_FULL_TOPIC "topic complet"
|
||||
|
||||
#define D_LOGGING_PARAMETERS "Paramètres journalisation"
|
||||
#define D_SERIAL_LOG_LEVEL "Niveau de journalisation série"
|
||||
#define D_WEB_LOG_LEVEL "Niveau de journalisation web"
|
||||
#define D_SYS_LOG_LEVEL "Niveau syslog"
|
||||
#define D_MORE_DEBUG "Plus de debug"
|
||||
#define D_SYSLOG_HOST "Host syslog"
|
||||
#define D_SYSLOG_PORT "Host syslog"
|
||||
#define D_TELEMETRY_PERIOD "Période télémetrie"
|
||||
|
||||
#define D_OTHER_PARAMETERS "Autres paramètres"
|
||||
#define D_WEB_ADMIN_PASSWORD "Mot de passe Web Admin"
|
||||
#define D_MQTT_ENABLE "MQTT activé"
|
||||
#define D_FRIENDLY_NAME "Surnom"
|
||||
#define D_BELKIN_WEMO "Belkin WeMo"
|
||||
#define D_HUE_BRIDGE "Hue Bridge"
|
||||
#define D_SINGLE_DEVICE "module unique"
|
||||
#define D_MULTI_DEVICE "multi module"
|
||||
|
||||
#define D_SAVE_CONFIGURATION "Enregistrer configuration"
|
||||
#define D_CONFIGURATION_SAVED "Configuration enregistré"
|
||||
#define D_CONFIGURATION_RESET "Configuration réinitialisé"
|
||||
|
||||
#define D_PROGRAM_VERSION "Version Programme"
|
||||
#define D_BUILD_DATE_AND_TIME "Date & Heure de build"
|
||||
#define D_CORE_AND_SDK_VERSION "Version Core/SDK"
|
||||
#define D_FLASH_WRITE_COUNT "Compteur écriture flash"
|
||||
#define D_MAC_ADDRESS "Adresse MAC"
|
||||
#define D_MQTT_HOST "Hôte MQTT"
|
||||
#define D_MQTT_PORT "Port MQTT"
|
||||
#define D_MQTT_CLIENT "Client MQTT"
|
||||
#define D_MQTT_USER "Utilisateur MQTT"
|
||||
#define D_MQTT_TOPIC "Topic MQTT"
|
||||
#define D_MQTT_GROUP_TOPIC "Groupe topic MQTT"
|
||||
#define D_MQTT_FULL_TOPIC "Topic complet MQTT"
|
||||
#define D_MDNS_DISCOVERY "Découverte mDNS"
|
||||
#define D_MDNS_ADVERTISE "Annonce mDNS"
|
||||
#define D_ESP_CHIP_ID "ESP Chip Id"
|
||||
#define D_FLASH_CHIP_ID "Flash Chip Id"
|
||||
#define D_FLASH_CHIP_SIZE "Taille flash"
|
||||
#define D_FREE_PROGRAM_SPACE "Espace programme libre"
|
||||
|
||||
#define D_UPGRADE_BY_WEBSERVER "Mise à jour par serveur web"
|
||||
#define D_OTA_URL "URL OTA"
|
||||
#define D_START_UPGRADE "Lancer la mise à jour"
|
||||
#define D_UPGRADE_BY_FILE_UPLOAD "Mise à jour par téléchargement fichier"
|
||||
#define D_UPLOAD_STARTED "Téléchargement lancé"
|
||||
#define D_UPGRADE_STARTED "Mise à jour lancé"
|
||||
#define D_UPLOAD_DONE "Téléchargement terminé"
|
||||
#define D_UPLOAD_ERR_1 "Aucun fichier sélectionné"
|
||||
#define D_UPLOAD_ERR_2 "Espace insuffisant"
|
||||
#define D_UPLOAD_ERR_3 "Magic byte n'est pas 0xE9"
|
||||
#define D_UPLOAD_ERR_4 "La taille de la flash programme est plus grande que la taille réelle de la flash"
|
||||
#define D_UPLOAD_ERR_5 "Erreur comparaison buffer de téléchargement"
|
||||
#define D_UPLOAD_ERR_6 "Téléchargement échoué. Activation logging 3"
|
||||
#define D_UPLOAD_ERR_7 "Téléchargement annulé"
|
||||
#define D_UPLOAD_ERR_8 "Fichier invalide"
|
||||
#define D_UPLOAD_ERR_9 "Fichier trop grand"
|
||||
#define D_UPLOAD_ERROR_CODE "Code d'erreur téléchargement"
|
||||
|
||||
#define D_ENTER_COMMAND "Saisir commande"
|
||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Activer weblog 2 si response attendue"
|
||||
#define D_NEED_USER_AND_PASSWORD "Nécessite utilisateur=<username>&password=<password>"
|
||||
|
||||
// xdrv_wemohue.ino
|
||||
#define D_MULTICAST_DISABLED "Multicast désactivé"
|
||||
#define D_MULTICAST_REJOINED "Multicast (re)joint"
|
||||
#define D_MULTICAST_JOIN_FAILED "Multicast echec abonnement"
|
||||
#define D_FAILED_TO_SEND_RESPONSE "Echec d'envoi réponse"
|
||||
|
||||
#define D_WEMO "WeMo"
|
||||
#define D_WEMO_BASIC_EVENT "WeMo basic event"
|
||||
#define D_WEMO_EVENT_SERVICE "WeMo event service"
|
||||
#define D_WEMO_META_SERVICE "WeMo meta service"
|
||||
#define D_WEMO_SETUP "Réglage WeMo"
|
||||
#define D_RESPONSE_SENT "Response envoyé"
|
||||
|
||||
#define D_HUE "Hue"
|
||||
#define D_HUE_BRIDGE_SETUP "Réglage Hue"
|
||||
#define D_HUE_API_NOT_IMPLEMENTED "API Hue non implémentée"
|
||||
#define D_HUE_API "Hue API"
|
||||
#define D_HUE_POST_ARGS "Hue POST args"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 paquets response envoyés"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Paramètres Domoticz"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
#define D_DOMOTICZ_KEY_IDX "Key idx"
|
||||
#define D_DOMOTICZ_SWITCH_IDX "Switch idx"
|
||||
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
|
||||
#define D_DOMOTICZ_TEMP "Temp"
|
||||
#define D_DOMOTICZ_TEMP_HUM "Temp,Hum"
|
||||
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro"
|
||||
#define D_DOMOTICZ_POWER_ENERGY "Power,Energy"
|
||||
#define D_DOMOTICZ_ILLUMINANCE "Illuminance"
|
||||
#define D_DOMOTICZ_COUNT "Count"
|
||||
#define D_DOMOTICZ_VOLTAGE "Voltage"
|
||||
#define D_DOMOTICZ_CURRENT "Current"
|
||||
#define D_DOMOTICZ_AIRQUALITY "AirQuality"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Update timer"
|
||||
|
||||
// xsns_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energie aujourd'hui"
|
||||
#define D_ENERGY_YESTERDAY "Energie hier"
|
||||
#define D_ENERGY_TOTAL "Energie totale"
|
||||
|
||||
// xsns_05_ds18b20.ino
|
||||
#define D_SENSOR_BUSY "Capteur occupé"
|
||||
#define D_SENSOR_CRC_ERROR "Erreur CRC capteur"
|
||||
#define D_SENSORS_FOUND "Capteur trouvé"
|
||||
|
||||
// xsns_06_dht.ino
|
||||
#define D_TIMEOUT_WAITING_FOR "Expiré attend pour"
|
||||
#define D_START_SIGNAL_LOW "Signal démarrage bas"
|
||||
#define D_START_SIGNAL_HIGH "Signal démarrage haut"
|
||||
#define D_PULSE "pulse"
|
||||
#define D_CHECKSUM_FAILURE "Echec checksum"
|
||||
|
||||
// xsns_07_sht1x.ino
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Le capteur n'a pas ACK la commande"
|
||||
#define D_SHT1X_FOUND "SHT1X found"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "Particules"
|
||||
|
||||
// sonoff_template.h
|
||||
#define D_SENSOR_NONE "None"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
#define D_SENSOR_SI7021 "SI7021"
|
||||
#define D_SENSOR_DS18X20 "DS18x20"
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
#define D_SENSOR_RELAY "Relay" // Suffix "1i"
|
||||
#define D_SENSOR_LED "LED" // Suffix "1i"
|
||||
#define D_SENSOR_PWM "PWM" // Suffix "1"
|
||||
#define D_SENSOR_COUNTER "Counter" // Suffix "1"
|
||||
#define D_SENSOR_IRRECV "IRrecv"
|
||||
#define D_SENSOR_MHZ_RX "MHZ Rx"
|
||||
#define D_SENSOR_MHZ_TX "MHZ Tx"
|
||||
#define D_SENSOR_PZEM_RX "PZEM Rx"
|
||||
#define D_SENSOR_PZEM_TX "PZEM Tx"
|
||||
#define D_SENSOR_SAIR_RX "SAir Rx"
|
||||
#define D_SENSOR_SAIR_TX "SAir Tx"
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_HOUR "h"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "us"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "Min"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "ppd"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "secteurs"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
||||
// Log message prefix
|
||||
#define D_LOG_APPLICATION "APP: " // Application
|
||||
#define D_LOG_BRIDGE "BRG: " // Bridge
|
||||
#define D_LOG_CONFIG "CFG: " // Settings
|
||||
#define D_LOG_COMMAND "CMD: " // Command
|
||||
#define D_LOG_DEBUG "DBG: " // Debug
|
||||
#define D_LOG_DHT "DHT: " // DHT sensor
|
||||
#define D_LOG_DOMOTICZ "DOM: " // Domoticz
|
||||
#define D_LOG_DSB "DSB: " // DS18xB20 sensor
|
||||
#define D_LOG_HTTP "HTP: " // HTTP webserver
|
||||
#define D_LOG_I2C "I2C: " // I2C
|
||||
#define D_LOG_IRR "IRR: " // Infra Red Received
|
||||
#define D_LOG_LOG "LOG: " // Logging
|
||||
#define D_LOG_MODULE "MOD: " // Module
|
||||
#define D_LOG_MDNS "DNS: " // mDNS
|
||||
#define D_LOG_MQTT "MQT: " // MQTT
|
||||
#define D_LOG_OTHER "OTH: " // Other
|
||||
#define D_LOG_RESULT "RSL: " // Result
|
||||
#define D_LOG_RFR "RFR: " // RF Received
|
||||
#define D_LOG_SERIAL "SER: " // Serial
|
||||
#define D_LOG_SHT1 "SHT: " // SHT1x sensor
|
||||
#define D_LOG_UPLOAD "UPL: " // Upload
|
||||
#define D_LOG_UPNP "UPP: " // UPnP
|
||||
#define D_LOG_WIFI "WIF: " // Wifi
|
||||
|
||||
#endif // _LANGUAGE_FR_FR_H_
|
||||
@ -30,6 +30,8 @@
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "-"
|
||||
#define D_MONTH_DAY_SEPARATOR "-"
|
||||
@ -51,7 +53,7 @@
|
||||
#define D_AUTO "AUTO"
|
||||
#define D_BLINK "Blink"
|
||||
#define D_BLINKOFF "BlinkOff"
|
||||
#define D_BOOT_COUNT "Boot Count"
|
||||
#define D_BOOT_COUNT "Numero di boot"
|
||||
#define D_BRIGHTLIGHT "Luminoso"
|
||||
#define D_BUTTON "Pulsante"
|
||||
#define D_BY "da" // Written by me
|
||||
@ -60,7 +62,7 @@
|
||||
#define D_CO2 "CO2"
|
||||
#define D_CODE "codice" // Button code
|
||||
#define D_COLDLIGHT "Fredda"
|
||||
#define D_COMMAND "Command"
|
||||
#define D_COMMAND "Comando"
|
||||
#define D_CONNECTED "Connesso"
|
||||
#define D_COUNT "Conteggio"
|
||||
#define D_COUNTER "Contatore"
|
||||
@ -74,30 +76,30 @@
|
||||
#define D_DST_TIME "DST"
|
||||
#define D_EMULATION "Emulazione"
|
||||
#define D_ENABLED "Abilitato"
|
||||
#define D_ERASE "Erase"
|
||||
#define D_ERROR "Error"
|
||||
#define D_ERASE "Cancellare"
|
||||
#define D_ERROR "Errore"
|
||||
#define D_FAHRENHEIT "Fahrenheit"
|
||||
#define D_FAILED "Fallito"
|
||||
#define D_FALLBACK "Fallback"
|
||||
#define D_FALLBACK "Riserva"
|
||||
#define D_FALLBACK_TOPIC "Topic Riserva"
|
||||
#define D_FALSE "False"
|
||||
#define D_FALSE "Falso"
|
||||
#define D_FILE "File"
|
||||
#define D_FREE_MEMORY "Memoria Libera"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Gruppo"
|
||||
#define D_HOST "Host"
|
||||
#define D_HOSTNAME "Hostname"
|
||||
#define D_HOSTNAME "Nome Host"
|
||||
#define D_HUMIDITY "Umidita'"
|
||||
#define D_ILLUMINANCE "Illuminazione"
|
||||
#define D_IMMEDIATE "immediato" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INDEX "Indice"
|
||||
#define D_INFO "Info"
|
||||
#define D_INITIALIZED "Inizializzato"
|
||||
#define D_IP_ADDRESS "Indirizzo IP"
|
||||
#define D_LIGHT "Luce"
|
||||
#define D_LWT "LWT"
|
||||
#define D_MODULE "Module"
|
||||
#define D_MODULE "Modulo"
|
||||
#define D_MQTT "MQTT"
|
||||
#define D_MULTI_PRESS "multi-pressione"
|
||||
#define D_NOISE "Rumore"
|
||||
@ -115,10 +117,10 @@
|
||||
#define D_PRESSUREATSEALEVEL "Pressione al livello del mare"
|
||||
#define D_PROGRAM_FLASH_SIZE "Dimensione Flash Programma"
|
||||
#define D_PROGRAM_SIZE "Dimensione Programma"
|
||||
#define D_PROJECT "Project"
|
||||
#define D_PROJECT "Progetto"
|
||||
#define D_RECEIVED "Ricevuto"
|
||||
#define D_RESTART "Riavvio"
|
||||
#define D_RESTARTING "Restarting"
|
||||
#define D_RESTARTING "Riavviando"
|
||||
#define D_RESTART_REASON "Causa Riavvio"
|
||||
#define D_RESTORE "ripristino"
|
||||
#define D_RETAINED "salvato"
|
||||
@ -130,8 +132,8 @@
|
||||
#define D_STOP "Stop"
|
||||
#define D_SUBNET_MASK "Maschera sottorete"
|
||||
#define D_SUBSCRIBE_TO "Sottoscrivi a"
|
||||
#define D_SUCCESSFUL "Successful"
|
||||
#define D_TEMPERATURE "Temperature"
|
||||
#define D_SUCCESSFUL "Riuscito"
|
||||
#define D_TEMPERATURE "Temperatura"
|
||||
#define D_TO "a"
|
||||
#define D_TOGGLE "Toggle"
|
||||
#define D_TOPIC "Topic"
|
||||
@ -143,12 +145,13 @@
|
||||
#define D_USER "Utente"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_LEVEL "Livello UV"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VERSION "Versione"
|
||||
#define D_VOLTAGE "Tensione"
|
||||
#define D_WARMLIGHT "Calda"
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "ATTENZIONE Questa versione non supporta il salvataggio delle impostazioni"
|
||||
#define D_LEVEL_10 "level 1-0"
|
||||
#define D_LEVEL_01 "level 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Log seriale disabilitato"
|
||||
@ -334,19 +337,6 @@
|
||||
#define D_HUE_POST_ARGS "Hue POST argomenti"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 pacchetti di risposta inviati"
|
||||
|
||||
// xdrv_02_irremote.ino
|
||||
#define D_JSON_INVALID_JSON "JSON non valido"
|
||||
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocollo non supportato"
|
||||
#define D_JSON_IR_PROTOCOL "PROTOCOL"
|
||||
#define D_JSON_IR_BITS "BITS"
|
||||
#define D_JSON_IR_DATA "DATA"
|
||||
#define D_JSON_IRHVAC_VENDOR "VENDOR"
|
||||
#define D_JSON_IRHVAC_POWER "POWER"
|
||||
#define D_JSON_IRHVAC_MODE "MODE"
|
||||
#define D_JSON_IRHVAC_FANSPEED "FANSPEED"
|
||||
#define D_JSON_IRHVAC_TEMP "TEMP"
|
||||
#define D_JSON_IRRECEIVED "IrReceived"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Parametri Domoticz"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
@ -364,7 +354,7 @@
|
||||
#define D_DOMOTICZ_AIRQUALITY "AirQuality"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Intervallo di aggiornamento"
|
||||
|
||||
// xsns_03_energy.ino
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energia Oggi"
|
||||
#define D_ENERGY_YESTERDAY "Energia Ieri"
|
||||
#define D_ENERGY_TOTAL "Energia Totale"
|
||||
@ -385,8 +375,12 @@
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensore non ha eseguito il comando ACK"
|
||||
#define D_SHT1X_FOUND "SHT1X trovato"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "Particelle"
|
||||
|
||||
// sonoff_template.h
|
||||
// Max string length is 8 characters including suffixes
|
||||
#define D_SENSOR_NONE "None"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
@ -412,6 +406,7 @@
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
@ -419,11 +414,14 @@
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "us"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "Min"
|
||||
#define D_UNIT_PPM "ppm"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "ppd"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "settori"
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "-"
|
||||
#define D_MONTH_DAY_SEPARATOR "-"
|
||||
@ -45,7 +47,7 @@
|
||||
|
||||
// Common
|
||||
#define D_ADMIN "Admin"
|
||||
#define D_AIR_QUALITY "Lucht kwalitiet"
|
||||
#define D_AIR_QUALITY "Lucht kwaliteit"
|
||||
#define D_AP "AP" // Access Point
|
||||
#define D_AS "als"
|
||||
#define D_AUTO "AUTO"
|
||||
@ -149,6 +151,7 @@
|
||||
#define D_WEB_SERVER "Webserver"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "WAARSCHUWING Deze versie bewaart geen instellingen"
|
||||
#define D_LEVEL_10 "niveau 1-0"
|
||||
#define D_LEVEL_01 "niveau 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Serieel logging uitgeschakeld"
|
||||
@ -334,19 +337,6 @@
|
||||
#define D_HUE_POST_ARGS "Hue POST argumenten"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 antwoord paketten verstuurd"
|
||||
|
||||
// xdrv_02_irremote.ino
|
||||
#define D_JSON_INVALID_JSON "Ongeldig JSON"
|
||||
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol wordt niet ondersteund"
|
||||
#define D_JSON_IR_PROTOCOL "PROTOCOL"
|
||||
#define D_JSON_IR_BITS "BITS"
|
||||
#define D_JSON_IR_DATA "DATA"
|
||||
#define D_JSON_IRHVAC_VENDOR "VENDOR"
|
||||
#define D_JSON_IRHVAC_POWER "POWER"
|
||||
#define D_JSON_IRHVAC_MODE "MODE"
|
||||
#define D_JSON_IRHVAC_FANSPEED "FANSPEED"
|
||||
#define D_JSON_IRHVAC_TEMP "TEMP"
|
||||
#define D_JSON_IRRECEIVED "IrReceived"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
@ -364,7 +354,7 @@
|
||||
#define D_DOMOTICZ_AIRQUALITY "AirQuality"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Bijwerk timer"
|
||||
|
||||
// xsns_03_energy.ino
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Verbruik vandaag"
|
||||
#define D_ENERGY_YESTERDAY "Verbruik gisteren"
|
||||
#define D_ENERGY_TOTAL "Verbruik totaal"
|
||||
@ -385,8 +375,12 @@
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Geen opdracht ACK van sensor"
|
||||
#define D_SHT1X_FOUND "SHT1X gevonden"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "Stofdeeltjes"
|
||||
|
||||
// sonoff_template.h
|
||||
// Max string length is 8 characters including suffixes
|
||||
#define D_SENSOR_NONE "Geen"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
@ -412,6 +406,7 @@
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
@ -419,11 +414,14 @@
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "us"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "Min"
|
||||
#define D_UNIT_PPM "ppm"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "ppd"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sectoren"
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "-"
|
||||
#define D_MONTH_DAY_SEPARATOR "-"
|
||||
@ -149,6 +151,7 @@
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "WARNING This version does not support persistent settings"
|
||||
#define D_LEVEL_10 "poziom 1-0"
|
||||
#define D_LEVEL_01 "poziom 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Wylaczony dziennik na porcie szeregowym"
|
||||
@ -334,19 +337,6 @@
|
||||
#define D_HUE_POST_ARGS "Hue POST args"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 pakiety odpowiedzi wysylane"
|
||||
|
||||
// xdrv_02_irremote.ino
|
||||
#define D_JSON_INVALID_JSON "Invalid JSON"
|
||||
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protokol nie jest obslugiwany"
|
||||
#define D_JSON_IR_PROTOCOL "PROTOCOL"
|
||||
#define D_JSON_IR_BITS "BITS"
|
||||
#define D_JSON_IR_DATA "DATA"
|
||||
#define D_JSON_IRHVAC_VENDOR "VENDOR"
|
||||
#define D_JSON_IRHVAC_POWER "POWER"
|
||||
#define D_JSON_IRHVAC_MODE "MODE"
|
||||
#define D_JSON_IRHVAC_FANSPEED "FANSPEED"
|
||||
#define D_JSON_IRHVAC_TEMP "TEMP"
|
||||
#define D_JSON_IRRECEIVED "IrReceived"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Parametry Domoticz"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
@ -364,7 +354,7 @@
|
||||
#define D_DOMOTICZ_AIRQUALITY "AirQuality"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Zaktualizuj czasomierz"
|
||||
|
||||
// xsns_03_energy.ino
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energia Dzisiaj"
|
||||
#define D_ENERGY_YESTERDAY "Energia Wczoraj"
|
||||
#define D_ENERGY_TOTAL "Energia suma"
|
||||
@ -385,8 +375,12 @@
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Czujnik nie otrzymal komendy ACK"
|
||||
#define D_SHT1X_FOUND "SHT1X znaleziony"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "Particals"
|
||||
|
||||
// sonoff_template.h
|
||||
// Max string length is 8 characters including suffixes
|
||||
#define D_SENSOR_NONE "Brak"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
@ -412,6 +406,7 @@
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
@ -419,11 +414,14 @@
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "us"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "Min"
|
||||
#define D_UNIT_PPM "ppm"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "ppd"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sektory"
|
||||
|
||||
457
sonoff/language/zh-CN.h
Normal file
457
sonoff/language/zh-CN.h
Normal file
@ -0,0 +1,457 @@
|
||||
/*
|
||||
zh-CN.h - localization for Chinese (Simplified) - China for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends (translated by killadm)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LANGUAGE_ZH_CN_H_
|
||||
#define _LANGUAGE_ZH_CN_H_
|
||||
|
||||
/*************************** ATTENTION *******************************\
|
||||
*
|
||||
* Due to memory constraints only UTF-8 is supported.
|
||||
* To save code space keep text as short as possible.
|
||||
* Time and Date provided by SDK can not be localized (yet).
|
||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
#define D_YEAR_MONTH_SEPARATOR "-"
|
||||
#define D_MONTH_DAY_SEPARATOR "-"
|
||||
#define D_DATE_TIME_SEPARATOR "T"
|
||||
#define D_HOUR_MINUTE_SEPARATOR ":"
|
||||
#define D_MINUTE_SECOND_SEPARATOR ":"
|
||||
|
||||
#define D_DAY3LIST "SunMonTueWedThuFriSat"
|
||||
#define D_MONTH3LIST "JanFebMarAprMayJunJulAugSepOctNovDec"
|
||||
|
||||
// Non JSON decimal separator
|
||||
#define D_DECIMAL_SEPARATOR "."
|
||||
|
||||
// Common
|
||||
#define D_ADMIN "Admin"
|
||||
#define D_AIR_QUALITY "空气质量"
|
||||
#define D_AP "AP" // Access Point
|
||||
#define D_AS "名称:"
|
||||
#define D_AUTO "自动"
|
||||
#define D_BLINK "闪烁"
|
||||
#define D_BLINKOFF "闪烁关"
|
||||
#define D_BOOT_COUNT "启动次数"
|
||||
#define D_BRIGHTLIGHT "亮度"
|
||||
#define D_BUTTON "按钮"
|
||||
#define D_BY "by" // Written by me
|
||||
#define D_BYTES "大小:"
|
||||
#define D_CELSIUS "摄氏"
|
||||
#define D_CO2 "二氧化碳"
|
||||
#define D_CODE "代码" // Button code
|
||||
#define D_COLDLIGHT "冷"
|
||||
#define D_COMMAND "命令:"
|
||||
#define D_CONNECTED "已连接"
|
||||
#define D_COUNT "数量:"
|
||||
#define D_COUNTER "Counter"
|
||||
#define D_CURRENT "电流" // As in Voltage and Current
|
||||
#define D_DATA "数据:"
|
||||
#define D_DARKLIGHT "Dark"
|
||||
#define D_DEBUG "调试"
|
||||
#define D_DISABLED "禁用"
|
||||
#define D_DNS_SERVER "DNS服务器"
|
||||
#define D_DONE "完成"
|
||||
#define D_DST_TIME "DST"
|
||||
#define D_EMULATION "设备模拟"
|
||||
#define D_ENABLED "启用"
|
||||
#define D_ERASE "擦除"
|
||||
#define D_ERROR "错误"
|
||||
#define D_FAHRENHEIT "华氏"
|
||||
#define D_FAILED "失败"
|
||||
#define D_FALLBACK "Fallback"
|
||||
#define D_FALLBACK_TOPIC "Fallback Topic"
|
||||
#define D_FALSE "False"
|
||||
#define D_FILE "文件:"
|
||||
#define D_FREE_MEMORY "空闲内存"
|
||||
#define D_GAS "气体"
|
||||
#define D_GATEWAY "网关"
|
||||
#define D_GROUP "组:"
|
||||
#define D_HOST "主机"
|
||||
#define D_HOSTNAME "主机名"
|
||||
#define D_HUMIDITY "湿度"
|
||||
#define D_ILLUMINANCE "照度"
|
||||
#define D_IMMEDIATE "immediate" // Button immediate
|
||||
#define D_INDEX "索引:"
|
||||
#define D_INFO "信息"
|
||||
#define D_INITIALIZED "初始化完成"
|
||||
#define D_IP_ADDRESS "IP地址"
|
||||
#define D_LIGHT "灯"
|
||||
#define D_LWT "LWT"
|
||||
#define D_MODULE "模块"
|
||||
#define D_MQTT "MQTT"
|
||||
#define D_MULTI_PRESS "多次按键"
|
||||
#define D_NOISE "嘈杂"
|
||||
#define D_NONE "无"
|
||||
#define D_OFF "关"
|
||||
#define D_OFFLINE "离线"
|
||||
#define D_OK "好"
|
||||
#define D_ON "开"
|
||||
#define D_ONLINE "在线"
|
||||
#define D_PASSWORD "密码"
|
||||
#define D_PORT "端口"
|
||||
#define D_POWER_FACTOR "功率因数"
|
||||
#define D_POWERUSAGE "功率"
|
||||
#define D_PRESSURE "气压"
|
||||
#define D_PRESSUREATSEALEVEL "海平面气压"
|
||||
#define D_PROGRAM_FLASH_SIZE "固件 Flash 大小"
|
||||
#define D_PROGRAM_SIZE "固件大小"
|
||||
#define D_PROJECT "项目:"
|
||||
#define D_RECEIVED "已接收"
|
||||
#define D_RESTART "重启"
|
||||
#define D_RESTARTING "正在重启"
|
||||
#define D_RESTART_REASON "重启原因"
|
||||
#define D_RESTORE "恢复"
|
||||
#define D_RETAINED "已保留"
|
||||
#define D_SAVE "保存"
|
||||
#define D_SENSOR "传感器"
|
||||
#define D_SSID "名称"
|
||||
#define D_START "开始"
|
||||
#define D_STD_TIME "STD"
|
||||
#define D_STOP "停止"
|
||||
#define D_SUBNET_MASK "子网掩码"
|
||||
#define D_SUBSCRIBE_TO "订阅"
|
||||
#define D_SUCCESSFUL "成功"
|
||||
#define D_TEMPERATURE "温度"
|
||||
#define D_TO "to"
|
||||
#define D_TOGGLE "切换"
|
||||
#define D_TOPIC "主题"
|
||||
#define D_TRANSMIT "发送"
|
||||
#define D_TRUE "True"
|
||||
#define D_UPGRADE "升级"
|
||||
#define D_UPLOAD "上传"
|
||||
#define D_UPTIME "运行时间"
|
||||
#define D_USER "用户名"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_LEVEL "紫外线水平"
|
||||
#define D_VERSION "版本"
|
||||
#define D_VOLTAGE "电压"
|
||||
#define D_WARMLIGHT "暖"
|
||||
#define D_WEB_SERVER "Web Server"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "警告:精简固件不支持配置持久化保存"
|
||||
#define D_LEVEL_10 "level 1-0"
|
||||
#define D_LEVEL_01 "level 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "串口日志已禁用"
|
||||
#define D_SYSLOG_LOGGING_REENABLED "Syslog 日志已开启"
|
||||
|
||||
#define D_SET_BAUDRATE_TO "设置波特率为:"
|
||||
#define D_RECEIVED_TOPIC "接收到的主题:"
|
||||
#define D_DATA_SIZE "数据大小:"
|
||||
#define D_ANALOG_INPUT "Analog"
|
||||
|
||||
#define D_FINGERPRINT "验证 TLS 指纹..."
|
||||
#define D_TLS_CONNECT_FAILED_TO "TLS 连接失败"
|
||||
#define D_RETRY_IN "重试倒计时:"
|
||||
#define D_VERIFIED "验证成功"
|
||||
#define D_INSECURE "指纹无效导致连接不安全"
|
||||
#define D_CONNECT_FAILED_TO "连接失败:"
|
||||
|
||||
// support.ino
|
||||
#define D_OSWATCH "osWatch"
|
||||
#define D_BLOCKED_LOOP "Blocked Loop"
|
||||
#define D_WPS_FAILED_WITH_STATUS "WPSconfig FAILED with status"
|
||||
#define D_ACTIVE_FOR_3_MINUTES "active for 3 minutes"
|
||||
#define D_FAILED_TO_START "未能启动"
|
||||
#define D_PATCH_ISSUE_2186 "Patch issue 2186"
|
||||
#define D_CONNECTING_TO_AP "连接到 AP"
|
||||
#define D_IN_MODE "模式:"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "连接失败,因为没有获取到IP地址"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "连接失败,无法连接AP"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "连接失败,AP密码不正确"
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "连接失败,AP超时"
|
||||
#define D_ATTEMPTING_CONNECTION "尝试连接..."
|
||||
#define D_CHECKING_CONNECTION "检查连接..."
|
||||
#define D_QUERY_DONE "查询完成。 发现MQTT服务"
|
||||
#define D_MQTT_SERVICE_FOUND "发现MQTT服务:"
|
||||
#define D_FOUND_AT "found at"
|
||||
#define D_SYSLOG_HOST_NOT_FOUND "Syslog主机未找到"
|
||||
|
||||
// settings.ino
|
||||
#define D_SAVED_TO_FLASH_AT "保存到 flash:"
|
||||
#define D_LOADED_FROM_FLASH_AT "从 flash 载入"
|
||||
#define D_USE_DEFAULTS "使用默认设置"
|
||||
#define D_ERASED_SECTOR "擦除删除"
|
||||
|
||||
// webserver.ino
|
||||
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本过低 - 请升级"
|
||||
#define D_WEBSERVER_ACTIVE_ON "Web服务器:"
|
||||
#define D_WITH_IP_ADDRESS "IP地址:"
|
||||
#define D_WEBSERVER_STOPPED "Web 服务器已停止"
|
||||
#define D_FILE_NOT_FOUND "文件未找到"
|
||||
#define D_REDIRECTED "重定向到认证页面"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager set AccessPoint and keep Station"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager 设置接入点"
|
||||
#define D_TRYING_TO_CONNECT "尝试将设备连接到网络"
|
||||
|
||||
#define D_RESTART_IN "重启需要"
|
||||
#define D_SECONDS "秒"
|
||||
#define D_DEVICE_WILL_RESTART "设备将在几分钟内重启"
|
||||
#define D_BUTTON_TOGGLE "状态切换"
|
||||
#define D_CONFIGURATION "设置"
|
||||
#define D_INFORMATION "信息"
|
||||
#define D_FIRMWARE_UPGRADE "固件升级"
|
||||
#define D_CONSOLE "控制台"
|
||||
#define D_CONFIRM_RESTART "确认重启"
|
||||
|
||||
#define D_CONFIGURE_MODULE "模块设置"
|
||||
#define D_CONFIGURE_WIFI "WiFi设置"
|
||||
#define D_CONFIGURE_MQTT "MQTT设置"
|
||||
#define D_CONFIGURE_DOMOTICZ "Domoticz设置"
|
||||
#define D_CONFIGURE_LOGGING "日志设置"
|
||||
#define D_CONFIGURE_OTHER "其他设置"
|
||||
#define D_CONFIRM_RESET_CONFIGURATION "确认重置配置"
|
||||
#define D_RESET_CONFIGURATION "重置配置"
|
||||
#define D_BACKUP_CONFIGURATION "备份配置"
|
||||
#define D_RESTORE_CONFIGURATION "还原配置"
|
||||
#define D_MAIN_MENU "主菜单"
|
||||
|
||||
#define D_MODULE_PARAMETERS "模块设置"
|
||||
#define D_MODULE_TYPE "模块类型"
|
||||
#define D_GPIO "GPIO"
|
||||
#define D_SERIAL_IN "串口输入(RX)"
|
||||
#define D_SERIAL_OUT "串口输出(TX)"
|
||||
|
||||
#define D_WIFI_PARAMETERS "Wifi设置"
|
||||
#define D_SCAN_FOR_WIFI_NETWORKS "扫描无线网络"
|
||||
#define D_SCAN_DONE "扫描完毕"
|
||||
#define D_NO_NETWORKS_FOUND "未找到任何网络"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "刷新并重试"
|
||||
#define D_DUPLICATE_ACCESSPOINT "重复AP"
|
||||
#define D_SKIPPING_LOW_QUALITY "忽略弱信号网络"
|
||||
#define D_RSSI "RSSI"
|
||||
#define D_WEP "WEP"
|
||||
#define D_WPA_PSK "WPA PSK"
|
||||
#define D_WPA2_PSK "WPA2 PSK"
|
||||
#define D_AP1_SSID "AP1 名称"
|
||||
#define D_AP1_PASSWORD "AP1 密码"
|
||||
#define D_AP2_SSID "AP2 名称"
|
||||
#define D_AP2_PASSWORD "AP2 密码"
|
||||
|
||||
#define D_MQTT_PARAMETERS "MQTT设置"
|
||||
#define D_CLIENT "客户端"
|
||||
#define D_FULL_TOPIC "完整主题"
|
||||
|
||||
#define D_LOGGING_PARAMETERS "日志设置"
|
||||
#define D_SERIAL_LOG_LEVEL "串口日志级别"
|
||||
#define D_WEB_LOG_LEVEL "Web 日志级别"
|
||||
#define D_SYS_LOG_LEVEL "Syslog 日志级别"
|
||||
#define D_MORE_DEBUG "全部调试"
|
||||
#define D_SYSLOG_HOST "Syslog 主机地址"
|
||||
#define D_SYSLOG_PORT "Syslog 端口"
|
||||
#define D_TELEMETRY_PERIOD "上报周期"
|
||||
|
||||
#define D_OTHER_PARAMETERS "其他设置"
|
||||
#define D_WEB_ADMIN_PASSWORD "WEB管理密码"
|
||||
#define D_MQTT_ENABLE "启用MQTT"
|
||||
#define D_FRIENDLY_NAME "昵称"
|
||||
#define D_BELKIN_WEMO "贝尔金 WeMo"
|
||||
#define D_HUE_BRIDGE "飞利浦 Hue 网桥"
|
||||
#define D_SINGLE_DEVICE "单设备"
|
||||
#define D_MULTI_DEVICE "多设备"
|
||||
|
||||
#define D_SAVE_CONFIGURATION "保存设置"
|
||||
#define D_CONFIGURATION_SAVED "设置已保存"
|
||||
#define D_CONFIGURATION_RESET "设置已重置"
|
||||
|
||||
#define D_PROGRAM_VERSION "固件版本"
|
||||
#define D_BUILD_DATE_AND_TIME "编译时间"
|
||||
#define D_CORE_AND_SDK_VERSION "内核版本"
|
||||
#define D_FLASH_WRITE_COUNT "刷机次数"
|
||||
#define D_MAC_ADDRESS "MAC地址"
|
||||
#define D_MQTT_HOST "MQTT主机"
|
||||
#define D_MQTT_PORT "MQTT端口"
|
||||
#define D_MQTT_CLIENT "MQTT客户端"
|
||||
#define D_MQTT_USER "MQTT用户名"
|
||||
#define D_MQTT_TOPIC "MQTT 主题(Topic)"
|
||||
#define D_MQTT_GROUP_TOPIC "MQTT 主题组(Group Topic)"
|
||||
#define D_MQTT_FULL_TOPIC "MQTT 完整主题(Full Topic)"
|
||||
#define D_MDNS_DISCOVERY "mDNS 发现"
|
||||
#define D_MDNS_ADVERTISE "mDNS 广播"
|
||||
#define D_ESP_CHIP_ID "ESP芯片ID"
|
||||
#define D_FLASH_CHIP_ID "Flash芯片ID"
|
||||
#define D_FLASH_CHIP_SIZE "Flash大小"
|
||||
#define D_FREE_PROGRAM_SPACE "空闲程序空间"
|
||||
|
||||
#define D_UPGRADE_BY_WEBSERVER "通过Web升级"
|
||||
#define D_OTA_URL "OTA地址"
|
||||
#define D_START_UPGRADE "开始升级"
|
||||
#define D_UPGRADE_BY_FILE_UPLOAD "通过文件升级"
|
||||
#define D_UPLOAD_STARTED "开始上传"
|
||||
#define D_UPGRADE_STARTED "开始升级"
|
||||
#define D_UPLOAD_DONE "上传完成"
|
||||
#define D_UPLOAD_ERR_1 "没有选择文件"
|
||||
#define D_UPLOAD_ERR_2 "没有足够空间"
|
||||
#define D_UPLOAD_ERR_3 "固件头不是 0xE9"
|
||||
#define D_UPLOAD_ERR_4 "固件太大"
|
||||
#define D_UPLOAD_ERR_5 "上传缓冲区不匹配"
|
||||
#define D_UPLOAD_ERR_6 "上传失败。 启用日志记录 3"
|
||||
#define D_UPLOAD_ERR_7 "上传取消"
|
||||
#define D_UPLOAD_ERR_8 "错误的固件"
|
||||
#define D_UPLOAD_ERR_9 "固件太大"
|
||||
#define D_UPLOAD_ERROR_CODE "上传错误代码"
|
||||
|
||||
#define D_ENTER_COMMAND "输入命令"
|
||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "如果预期响应,则启用Weblog 2"
|
||||
#define D_NEED_USER_AND_PASSWORD "需要 user=<用户名>&password=<密码>"
|
||||
|
||||
// xdrv_wemohue.ino
|
||||
#define D_MULTICAST_DISABLED "组播已禁用"
|
||||
#define D_MULTICAST_REJOINED "组播已(重新)加入"
|
||||
#define D_MULTICAST_JOIN_FAILED "组播加入失败"
|
||||
#define D_FAILED_TO_SEND_RESPONSE "请求发送失败"
|
||||
|
||||
#define D_WEMO "WeMo"
|
||||
#define D_WEMO_BASIC_EVENT "WeMo 基础事件"
|
||||
#define D_WEMO_EVENT_SERVICE "WeMo 事件服务"
|
||||
#define D_WEMO_META_SERVICE "WeMo meta 服务"
|
||||
#define D_WEMO_SETUP "WeMo 设置"
|
||||
#define D_RESPONSE_SENT "发送请求"
|
||||
|
||||
#define D_HUE "Hue"
|
||||
#define D_HUE_BRIDGE_SETUP "Hue 设置"
|
||||
#define D_HUE_API_NOT_IMPLEMENTED "Hue API 未实现"
|
||||
#define D_HUE_API "Hue API"
|
||||
#define D_HUE_POST_ARGS "Hue POST 参数"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 请求包发送"
|
||||
|
||||
// xdrv_05_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Domoticz 设置"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
#define D_DOMOTICZ_KEY_IDX "Key idx"
|
||||
#define D_DOMOTICZ_SWITCH_IDX "开关 idx"
|
||||
#define D_DOMOTICZ_SENSOR_IDX "传感器 idx"
|
||||
#define D_DOMOTICZ_TEMP "温度"
|
||||
#define D_DOMOTICZ_TEMP_HUM "温度,湿度"
|
||||
#define D_DOMOTICZ_TEMP_HUM_BARO "温度,湿度,气压"
|
||||
#define D_DOMOTICZ_POWER_ENERGY "功率,电量"
|
||||
#define D_DOMOTICZ_ILLUMINANCE "照度"
|
||||
#define D_DOMOTICZ_COUNT "数值"
|
||||
#define D_DOMOTICZ_VOLTAGE "电压"
|
||||
#define D_DOMOTICZ_CURRENT "电流"
|
||||
#define D_DOMOTICZ_AIRQUALITY "空气质量"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "更新计时器"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "今日用电量"
|
||||
#define D_ENERGY_YESTERDAY "昨日用电量"
|
||||
#define D_ENERGY_TOTAL "总用电量"
|
||||
|
||||
// xsns_05_ds18b20.ino
|
||||
#define D_SENSOR_BUSY "传感器正忙"
|
||||
#define D_SENSOR_CRC_ERROR "传感器 CRC 校验错误"
|
||||
#define D_SENSORS_FOUND "发现传感器"
|
||||
|
||||
// xsns_06_dht.ino
|
||||
#define D_TIMEOUT_WAITING_FOR "等待超时"
|
||||
#define D_START_SIGNAL_LOW "开始低电平"
|
||||
#define D_START_SIGNAL_HIGH "开始高电平"
|
||||
#define D_PULSE "pulse"
|
||||
#define D_CHECKSUM_FAILURE "校验失败"
|
||||
|
||||
// xsns_07_sht1x.ino
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "传感器没有确认命令"
|
||||
#define D_SHT1X_FOUND "发现 SHT1X 传感器"
|
||||
|
||||
// xsns_18_pms5003.ino
|
||||
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
|
||||
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
|
||||
#define D_PARTICALS_BEYOND "颗粒物直径大于"
|
||||
|
||||
// sonoff_template.h
|
||||
#define D_SENSOR_NONE "None"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
#define D_SENSOR_SI7021 "SI7021"
|
||||
#define D_SENSOR_DS18X20 "DS18x20"
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
#define D_SENSOR_RELAY "Relay" // Suffix "1i"
|
||||
#define D_SENSOR_LED "Led" // Suffix "1i"
|
||||
#define D_SENSOR_PWM "PWM" // Suffix "1"
|
||||
#define D_SENSOR_COUNTER "Counter" // Suffix "1"
|
||||
#define D_SENSOR_IRRECV "IRrecv"
|
||||
#define D_SENSOR_MHZ_RX "MHZ Rx"
|
||||
#define D_SENSOR_MHZ_TX "MHZ Tx"
|
||||
#define D_SENSOR_PZEM_RX "PZEM Rx"
|
||||
#define D_SENSOR_PZEM_TX "PZEM Tx"
|
||||
#define D_SENSOR_SAIR_RX "SAir Rx"
|
||||
#define D_SENSOR_SAIR_TX "SAir Tx"
|
||||
#define D_SENSOR_SPI_CS "SPI CS"
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "安"
|
||||
#define D_UNIT_HOUR "时"
|
||||
#define D_UNIT_KILOOHM "千欧"
|
||||
#define D_UNIT_KILOWATTHOUR "千瓦时"
|
||||
#define D_UNIT_LUX "勒克斯"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "微克/立方米"
|
||||
#define D_UNIT_MICROMETER "微米"
|
||||
#define D_UNIT_MICROSECOND "微秒"
|
||||
#define D_UNIT_MILLIAMPERE "毫安"
|
||||
#define D_UNIT_MILLISECOND "毫秒"
|
||||
#define D_UNIT_MINUTE "分"
|
||||
#define D_UNIT_PARTS_PER_DECILITER "每分升"
|
||||
#define D_UNIT_PARTS_PER_MILLION "ppm"
|
||||
#define D_UNIT_PRESSURE "百帕"
|
||||
#define D_UNIT_SECOND "秒"
|
||||
#define D_UNIT_SECTORS "扇区"
|
||||
#define D_UNIT_VOLT "伏"
|
||||
#define D_UNIT_WATT "瓦"
|
||||
#define D_UNIT_WATTHOUR "瓦时"
|
||||
|
||||
// Log message prefix
|
||||
#define D_LOG_APPLICATION "APP: " // Application
|
||||
#define D_LOG_BRIDGE "BRG: " // Bridge
|
||||
#define D_LOG_CONFIG "CFG: " // Settings
|
||||
#define D_LOG_COMMAND "CMD: " // Command
|
||||
#define D_LOG_DEBUG "DBG: " // Debug
|
||||
#define D_LOG_DHT "DHT: " // DHT sensor
|
||||
#define D_LOG_DOMOTICZ "DOM: " // Domoticz
|
||||
#define D_LOG_DSB "DSB: " // DS18xB20 sensor
|
||||
#define D_LOG_HTTP "HTP: " // HTTP webserver
|
||||
#define D_LOG_I2C "I2C: " // I2C
|
||||
#define D_LOG_IRR "IRR: " // Infra Red Received
|
||||
#define D_LOG_LOG "LOG: " // Logging
|
||||
#define D_LOG_MODULE "MOD: " // Module
|
||||
#define D_LOG_MDNS "DNS: " // mDNS
|
||||
#define D_LOG_MQTT "MQT: " // MQTT
|
||||
#define D_LOG_OTHER "OTH: " // Other
|
||||
#define D_LOG_RESULT "RSL: " // Result
|
||||
#define D_LOG_RFR "RFR: " // RF Received
|
||||
#define D_LOG_SERIAL "SER: " // Serial
|
||||
#define D_LOG_SHT1 "SHT: " // SHT1x sensor
|
||||
#define D_LOG_UPLOAD "UPL: " // Upload
|
||||
#define D_LOG_UPNP "UPP: " // UPnP
|
||||
#define D_LOG_WIFI "WIF: " // Wifi
|
||||
|
||||
#endif // _LANGUAGE_ZH_CN_H_
|
||||
@ -44,9 +44,9 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t ws_clock_reverse : 1; // bit 16 (v5.8.1)
|
||||
uint32_t decimal_text : 1; // bit 17 (v5.8.1)
|
||||
uint32_t light_signal : 1; // bit 18 (v5.10.0c)
|
||||
uint32_t spare19 : 1;
|
||||
uint32_t voltage_resolution : 1; // Replaced by below
|
||||
uint32_t spare21 : 1;
|
||||
uint32_t hass_discovery : 1; // bit 19 (v5.11.1a)
|
||||
uint32_t not_power_linked : 1; // bit 20 (v5.11.1f)
|
||||
uint32_t no_power_on_check : 1; // bit 21 (v5.11.1i)
|
||||
uint32_t spare22 : 1;
|
||||
uint32_t spare23 : 1;
|
||||
uint32_t spare24 : 1;
|
||||
@ -57,15 +57,6 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t spare29 : 1;
|
||||
uint32_t spare30 : 1;
|
||||
uint32_t spare31 : 1;
|
||||
/*
|
||||
uint32_t wattage_resolution : 1;
|
||||
uint32_t voltage_resolution : 1;
|
||||
uint32_t emulation : 2;
|
||||
uint32_t energy_resolution : 3;
|
||||
uint32_t pressure_resolution : 2;
|
||||
uint32_t humidity_resolution : 2;
|
||||
uint32_t temperature_resolution : 2;
|
||||
*/
|
||||
};
|
||||
} SysBitfield;
|
||||
|
||||
@ -161,12 +152,12 @@ struct SYSCFG {
|
||||
uint16_t domoticz_update_timer; // 340
|
||||
uint16_t pwm_range; // 342
|
||||
|
||||
unsigned long domoticz_relay_idx[MAX_DOMOTICZ_IDX]; // 344
|
||||
unsigned long domoticz_key_idx[MAX_DOMOTICZ_IDX]; // 354
|
||||
unsigned long domoticz_relay_idx[MAX_DOMOTICZ_IDX]; // 344
|
||||
unsigned long domoticz_key_idx[MAX_DOMOTICZ_IDX]; // 354
|
||||
|
||||
unsigned long hlw_power_calibration; // 364
|
||||
unsigned long hlw_voltage_calibration; // 368
|
||||
unsigned long hlw_current_calibration; // 36C
|
||||
unsigned long energy_power_calibration; // 364
|
||||
unsigned long energy_voltage_calibration; // 368
|
||||
unsigned long energy_current_calibration; // 36C
|
||||
unsigned long energy_kWhtoday; // 370
|
||||
unsigned long energy_kWhyesterday; // 374
|
||||
uint16_t energy_kWhdoy; // 378
|
||||
@ -177,11 +168,11 @@ struct SYSCFG {
|
||||
uint16_t energy_min_current; // 382
|
||||
uint16_t energy_max_current; // 384
|
||||
uint16_t energy_max_power_limit; // 386 MaxPowerLimit
|
||||
uint16_t energy_max_power_limit_hold; // 388 MaxPowerLimitHold
|
||||
uint16_t energy_max_power_limit_window; // 38A MaxPowerLimitWindow
|
||||
uint16_t energy_max_power_safe_limit; // 38C MaxSafePowerLimit
|
||||
uint16_t energy_max_power_safe_limit_hold; // 38E MaxSafePowerLimitHold
|
||||
uint16_t energy_max_power_safe_limit_window; // 390 MaxSafePowerLimitWindow
|
||||
uint16_t energy_max_power_limit_hold; // 388 MaxPowerLimitHold
|
||||
uint16_t energy_max_power_limit_window; // 38A MaxPowerLimitWindow
|
||||
uint16_t energy_max_power_safe_limit; // 38C MaxSafePowerLimit
|
||||
uint16_t energy_max_power_safe_limit_hold; // 38E MaxSafePowerLimitHold
|
||||
uint16_t energy_max_power_safe_limit_window; // 390 MaxSafePowerLimitWindow
|
||||
uint16_t energy_max_energy; // 392 MaxEnergy
|
||||
uint16_t energy_max_energy_start; // 394 MaxEnergyStart
|
||||
uint16_t mqtt_retry; // 396
|
||||
@ -262,7 +253,7 @@ struct SYSCFG {
|
||||
struct RTCMEM {
|
||||
uint16_t valid; // 000
|
||||
byte oswatch_blocked_loop; // 002
|
||||
uint8_t unused; // 003
|
||||
uint8_t ota_loader; // 003
|
||||
unsigned long energy_kWhtoday; // 004
|
||||
unsigned long energy_kWhtotal; // 008
|
||||
unsigned long pulse_counter[MAX_COUNTERS]; // 00C
|
||||
@ -279,6 +270,7 @@ struct TIME_T {
|
||||
char name_of_month[4];
|
||||
uint16_t day_of_year;
|
||||
uint16_t year;
|
||||
unsigned long days;
|
||||
unsigned long valid;
|
||||
} RtcTime;
|
||||
|
||||
|
||||
@ -25,14 +25,28 @@
|
||||
#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo (single relay/light) or Hue Bridge emulation (multi relay/light) (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
|
||||
#endif
|
||||
|
||||
#ifndef USE_DISPLAY // Add Display Support for up to eigth Matrices
|
||||
#ifndef MTX_ADDRESS1 // Add Display Support for up to eigth Matrices
|
||||
#define MTX_ADDRESS1 0
|
||||
#endif
|
||||
#ifndef MTX_ADDRESS2
|
||||
#define MTX_ADDRESS2 0
|
||||
#endif
|
||||
#ifndef MTX_ADDRESS3
|
||||
#define MTX_ADDRESS3 0
|
||||
#endif
|
||||
#ifndef MTX_ADDRESS4
|
||||
#define MTX_ADDRESS4 0
|
||||
#endif
|
||||
#ifndef MTX_ADDRESS5
|
||||
#define MTX_ADDRESS5 0
|
||||
#endif
|
||||
#ifndef MTX_ADDRESS6
|
||||
#define MTX_ADDRESS6 0
|
||||
#endif
|
||||
#ifndef MTX_ADDRESS7
|
||||
#define MTX_ADDRESS7 0
|
||||
#endif
|
||||
#ifndef MTX_ADDRESS8
|
||||
#define MTX_ADDRESS8 0
|
||||
#endif
|
||||
|
||||
@ -109,7 +123,7 @@ void RtcSettingsDump()
|
||||
|
||||
for (row = 0; row < maxrow; row++) {
|
||||
idx = row * CFG_COLS;
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%04X:"), idx);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), idx);
|
||||
for (col = 0; col < CFG_COLS; col++) {
|
||||
if (!(col%4)) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data);
|
||||
@ -364,7 +378,7 @@ void SettingsDump(char* parms)
|
||||
|
||||
for (row = srow; row < maxrow; row++) {
|
||||
idx = row * CFG_COLS;
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%04X:"), idx);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), idx);
|
||||
for (col = 0; col < CFG_COLS; col++) {
|
||||
if (!(col%4)) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data);
|
||||
@ -416,6 +430,7 @@ void SettingsDefaultSet2()
|
||||
Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
|
||||
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
|
||||
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
|
||||
Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE;
|
||||
|
||||
Settings.flag2.emulation = EMULATION;
|
||||
|
||||
@ -463,9 +478,9 @@ void SettingsDefaultSet2()
|
||||
// Settings.domoticz_switch_idx[i] = 0;
|
||||
}
|
||||
|
||||
Settings.hlw_power_calibration = HLW_PREF_PULSE;
|
||||
Settings.hlw_voltage_calibration = HLW_UREF_PULSE;
|
||||
Settings.hlw_current_calibration = HLW_IREF_PULSE;
|
||||
Settings.energy_power_calibration = HLW_PREF_PULSE;
|
||||
Settings.energy_voltage_calibration = HLW_UREF_PULSE;
|
||||
Settings.energy_current_calibration = HLW_IREF_PULSE;
|
||||
// Settings.energy_kWhtoday = 0;
|
||||
// Settings.energy_kWhyesterday = 0;
|
||||
// Settings.energy_kWhdoy = 0;
|
||||
@ -830,13 +845,17 @@ void SettingsDelta()
|
||||
if (Settings.version < 0x05090102) {
|
||||
Settings.flag2.data = Settings.flag.data;
|
||||
Settings.flag2.data &= 0xFFE80000;
|
||||
Settings.flag2.voltage_resolution = Settings.flag.voltage_resolution;
|
||||
Settings.flag2.voltage_resolution = Settings.flag.not_power_linked;
|
||||
Settings.flag2.current_resolution = 3;
|
||||
Settings.ina219_mode = 0;
|
||||
}
|
||||
if (Settings.version < 0x050A0009) {
|
||||
SettingsDefaultSet_5_10_1();
|
||||
}
|
||||
if (Settings.version < 0x050B0107) {
|
||||
Settings.flag.not_power_linked = 0;
|
||||
}
|
||||
|
||||
|
||||
Settings.version = VERSION;
|
||||
SettingsSave(1);
|
||||
|
||||
@ -80,25 +80,26 @@ typedef unsigned long power_t; // Power (Relay) type
|
||||
#define STATES 20 // State loops per second
|
||||
#define SYSLOG_TIMER 600 // Seconds to restore syslog_level
|
||||
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
|
||||
#define OTA_ATTEMPTS 10 // Number of times to try fetching the new firmware
|
||||
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
|
||||
|
||||
#define INPUT_BUFFER_SIZE 250 // Max number of characters in (serial) command buffer
|
||||
#define INPUT_BUFFER_SIZE 255 // Max number of characters in (serial) command buffer
|
||||
#define CMDSZ 24 // Max number of characters in command
|
||||
#define TOPSZ 100 // Max number of characters in topic string
|
||||
#define LOGSZ 400 // Max number of characters in log
|
||||
#define MIN_MESSZ 893 // Min number of characters in MQTT message
|
||||
|
||||
#ifdef USE_MQTT_TLS
|
||||
#define MAX_LOG_LINES 10 // Max number of lines in weblog
|
||||
#define WEB_LOG_SIZE 2000 // Max number of characters in weblog
|
||||
#else
|
||||
#define MAX_LOG_LINES 20 // Max number of lines in weblog
|
||||
#define WEB_LOG_SIZE 4000 // Max number of characters in weblog
|
||||
#endif
|
||||
|
||||
#define MAX_BACKLOG 16 // Max number of commands in backlog (chk backlog_index and backlog_pointer code)
|
||||
#define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds
|
||||
|
||||
#define APP_BAUDRATE 115200 // Default serial baudrate
|
||||
#define MAX_STATUS 11 // Max number of status lines
|
||||
|
||||
#define XDRV_MAX 10 // Max number of allowed Xdrv drivers (Update xdrv_interface.ino if changed)
|
||||
#define XSNS_MAX 20 // Max number of allowed Xsns External Sensors (Update xsns_interface.ino if changed)
|
||||
|
||||
/*
|
||||
// Removed from esp8266 core since 20171105
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
@ -124,6 +125,12 @@ enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQ
|
||||
|
||||
enum EmulationOptions {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
||||
|
||||
enum TopicOptions { CMND, STAT, TELE, nu1, RESULT_OR_CMND, RESULT_OR_STAT, RESULT_OR_TELE };
|
||||
|
||||
enum ExecuteCommandPowerOptions { POWER_OFF, POWER_ON, POWER_TOGGLE, POWER_BLINK, POWER_BLINK_STOP, power_nu1, POWER_OFF_NO_STATE, POWER_ON_NO_STATE, power_nu2, POWER_SHOW_STATE };
|
||||
|
||||
enum PowerOnStateOptions { POWER_ALL_OFF, POWER_ALL_ON, POWER_ALL_SAVED_TOGGLE, POWER_ALL_SAVED, POWER_ALL_ALWAYS_ON, POWER_ALL_OFF_PULSETIME_ON };
|
||||
|
||||
enum ButtonStates {PRESSED, NOT_PRESSED};
|
||||
|
||||
enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8};
|
||||
@ -137,8 +144,14 @@ enum LichtSubtypes {LST_NONE, LST_SINGLE, LST_COLDWARM, LST_RGB, LST_RGBW, LST_R
|
||||
enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX};
|
||||
|
||||
enum XsnsFunctions {FUNC_INIT, FUNC_EVERY_50_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART,
|
||||
FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR};
|
||||
FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR};
|
||||
|
||||
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Extern global variables
|
||||
\*********************************************************************************************/
|
||||
|
||||
extern uint8_t light_device; // Light device number
|
||||
|
||||
#endif // _SONOFF_H_
|
||||
@ -19,17 +19,17 @@
|
||||
/*====================================================
|
||||
Prerequisites:
|
||||
- Change libraries/PubSubClient/src/PubSubClient.h
|
||||
#define MQTT_MAX_PACKET_SIZE 512
|
||||
#define MQTT_MAX_PACKET_SIZE 1000
|
||||
|
||||
- Select IDE Tools - Flash Mode: "DOUT"
|
||||
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
||||
====================================================*/
|
||||
|
||||
#define VERSION 0x050B0100
|
||||
#define VERSION_STRING "5.11.1" // Would be great to have a macro that fills this from VERSION ...
|
||||
#define VERSION 0x050C0000 // 5.12.0
|
||||
|
||||
// Location specific includes
|
||||
#include "sonoff.h" // Enumaration used in user_config.h
|
||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
#include "sonoff.h" // Enumeration used in user_config.h
|
||||
#include "user_config.h" // Fixed user configurable options
|
||||
#include "user_config_override.h" // Configuration overrides for user_config.h
|
||||
#include "i18n.h" // Language support configured by user_config.h
|
||||
@ -38,10 +38,12 @@
|
||||
|
||||
// Libraries
|
||||
#include <PubSubClient.h> // MQTT
|
||||
|
||||
// Max message size calculated by PubSubClient is (MQTT_MAX_PACKET_SIZE < 5 + 2 + strlen(topic) + plength)
|
||||
#if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MESSZ // If the max message size is too small, throw an error at compile time. See PubSubClient.cpp line 359
|
||||
#error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 512"
|
||||
#if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MIN_MESSZ // If the max message size is too small, throw an error at compile time. See PubSubClient.cpp line 359
|
||||
#error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 1000"
|
||||
#endif
|
||||
|
||||
#include <Ticker.h> // RTC, Energy, OSWatch
|
||||
#include <ESP8266WiFi.h> // MQTT, Ota, WifiManager
|
||||
#include <ESP8266HTTPClient.h> // MQTT, Ota
|
||||
@ -66,25 +68,25 @@
|
||||
#include "settings.h"
|
||||
|
||||
enum TasmotaCommands {
|
||||
CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_STATUS, CMND_POWERONSTATE, CMND_PULSETIME,
|
||||
CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION,
|
||||
CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_STATUS, CMND_STATE, CMND_POWERONSTATE, CMND_PULSETIME,
|
||||
CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SENSOR, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION,
|
||||
CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION, CMND_MODULE, CMND_MODULES,
|
||||
CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE,
|
||||
CMND_COUNTERDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG,
|
||||
CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME,
|
||||
CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_EMULATION,
|
||||
CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE,
|
||||
CMND_CFGDUMP, CMND_I2CSCAN, CMND_INA219MODE, CMND_EXCEPTION };
|
||||
CMND_CFGDUMP, CMND_I2CSCAN, CMND_EXCEPTION };
|
||||
const char kTasmotaCommands[] PROGMEM =
|
||||
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|"
|
||||
D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|"
|
||||
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|"
|
||||
D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SENSOR "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|"
|
||||
D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_MODULE "|" D_CMND_MODULES "|"
|
||||
D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|"
|
||||
D_CMND_COUNTERDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|"
|
||||
D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|"
|
||||
D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_EMULATION "|"
|
||||
D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
|
||||
D_CMND_CFGDUMP "|" D_CMND_I2CSCAN "|" D_CMND_INA219MODE
|
||||
D_CMND_CFGDUMP "|" D_CMND_I2CSCAN
|
||||
#ifdef DEBUG_THEO
|
||||
"|" D_CMND_EXCEPTION
|
||||
#endif
|
||||
@ -107,6 +109,7 @@ const char kOptionBlinkOff[] PROGMEM = "BLINKOFF|" D_BLINKOFF ;
|
||||
|
||||
// Global variables
|
||||
int baudrate = APP_BAUDRATE; // Serial interface baud rate
|
||||
SerialConfig serial_config = SERIAL_8N1; // Serial interface configuration 8 data bits, No parity, 1 stop bit
|
||||
byte serial_in_byte; // Received byte
|
||||
int serial_in_byte_counter = 0; // Index in receive buffer
|
||||
byte dual_hex_code = 0; // Sonoff dual input flag
|
||||
@ -120,12 +123,14 @@ int mqtt_connection_flag = 2; // MQTT connection messages flag
|
||||
int ota_state_flag = 0; // OTA state flag
|
||||
int ota_result = 0; // OTA result
|
||||
byte ota_retry_counter = OTA_ATTEMPTS; // OTA retry counter
|
||||
char *ota_url; // OTA url string
|
||||
int restart_flag = 0; // Sonoff restart flag
|
||||
int wifi_state_flag = WIFI_RESTART; // Wifi state flag
|
||||
int uptime = 0; // Current uptime in hours
|
||||
//int uptime = 0; // Current uptime in hours
|
||||
uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year
|
||||
boolean latest_uptime_flag = true; // Signal latest uptime
|
||||
int tele_period = 0; // Tele period timer
|
||||
byte web_log_index = 0; // Index in Web log buffer
|
||||
byte web_log_index = 1; // Index in Web log buffer (should never be 0)
|
||||
byte reset_web_log_flag = 0; // Reset web console log
|
||||
byte devices_present = 0; // Max number of devices supported
|
||||
int status_update_timer = 0; // Refresh initial status
|
||||
@ -181,19 +186,17 @@ uint8_t energy_flg = 1; // Energy monitor configured
|
||||
uint8_t i2c_flg = 0; // I2C configured
|
||||
uint8_t spi_flg = 0; // SPI configured
|
||||
uint8_t light_type = 0; // Light types
|
||||
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
|
||||
|
||||
boolean mdns_begun = false;
|
||||
|
||||
uint8_t xdrv_present = 0; // Number of drivers found
|
||||
boolean (*xdrv_func_ptr[XDRV_MAX])(byte); // Driver Function Pointers
|
||||
uint8_t xsns_present = 0; // Number of External Sensors found
|
||||
boolean (*xsns_func_ptr[XSNS_MAX])(byte); // External Sensor Function Pointers for simple implementation of sensors
|
||||
char my_version[33]; // Composed version string
|
||||
char my_hostname[33]; // Composed Wifi hostname
|
||||
char mqtt_client[33]; // Composed MQTT Clientname
|
||||
char serial_in_buffer[INPUT_BUFFER_SIZE + 2]; // Receive buffer
|
||||
char mqtt_data[MESSZ + TOPSZ]; // MQTT publish buffer (MESSZ) and web page ajax buffer (MESSZ + TOPSZ)
|
||||
char log_data[TOPSZ + MESSZ]; // Logging
|
||||
String web_log[MAX_LOG_LINES]; // Web log buffer
|
||||
char mqtt_client[33]; // Composed MQTT Clientname
|
||||
char serial_in_buffer[INPUT_BUFFER_SIZE]; // Receive buffer
|
||||
char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer
|
||||
char log_data[LOGSZ]; // Logging
|
||||
char web_log[WEB_LOG_SIZE] = {'\0'}; // Web log buffer
|
||||
String backlog[MAX_BACKLOG]; // Command backlog
|
||||
|
||||
/********************************************************************************************/
|
||||
@ -226,6 +229,10 @@ void GetMqttClient(char* output, const char* input, byte size)
|
||||
|
||||
void GetTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic)
|
||||
{
|
||||
/* prefix 0 = Cmnd
|
||||
prefix 1 = Stat
|
||||
prefix 2 = Tele
|
||||
*/
|
||||
char romram[CMDSZ];
|
||||
String fulltopic;
|
||||
|
||||
@ -286,7 +293,7 @@ void SetDevicePower(power_t rpower)
|
||||
{
|
||||
uint8_t state;
|
||||
|
||||
if (4 == Settings.poweronstate) { // All on and stay on
|
||||
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { // All on and stay on
|
||||
power = (1 << devices_present) -1;
|
||||
rpower = power;
|
||||
}
|
||||
@ -305,7 +312,7 @@ void SetDevicePower(power_t rpower)
|
||||
}
|
||||
}
|
||||
|
||||
XdrvSetPower(bitRead(rpower, devices_present -1));
|
||||
XdrvSetPower(rpower);
|
||||
|
||||
if ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module)) {
|
||||
Serial.write(0xA0);
|
||||
@ -349,18 +356,28 @@ void MqttSubscribe(char *topic)
|
||||
|
||||
void MqttPublishDirect(const char* topic, boolean retained)
|
||||
{
|
||||
char sretained[CMDSZ];
|
||||
char slog_type[10];
|
||||
|
||||
sretained[0] = '\0';
|
||||
snprintf_P(slog_type, sizeof(slog_type), PSTR(D_LOG_RESULT));
|
||||
|
||||
if (Settings.flag.mqtt_enabled) {
|
||||
mqtt_data[MESSZ -1] = '\0';
|
||||
if (MqttClient.publish(topic, mqtt_data, retained)) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT "%s = %s%s"), topic, mqtt_data, (retained) ? " (" D_RETAINED ")" : "");
|
||||
// MqttClient.loop(); // Do not use here! Will block previous publishes
|
||||
} else {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT "%s = %s"), topic, mqtt_data);
|
||||
snprintf_P(slog_type, sizeof(slog_type), PSTR(D_LOG_MQTT));
|
||||
if (retained) {
|
||||
snprintf_P(sretained, sizeof(sretained), PSTR(" (" D_RETAINED ")"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT "%s = %s"), strrchr(topic,'/')+1, mqtt_data);
|
||||
}
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%s = %s"), slog_type, (Settings.flag.mqtt_enabled) ? topic : strrchr(topic,'/')+1, mqtt_data);
|
||||
if (strlen(log_data) >= (sizeof(log_data) - strlen(sretained) -1)) {
|
||||
log_data[sizeof(log_data) - strlen(sretained) -5] = '\0';
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s ..."), log_data);
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s%s"), log_data, sretained);
|
||||
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
if (Settings.ledstate &0x04) {
|
||||
blinks++;
|
||||
@ -394,7 +411,7 @@ void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic, boolean reta
|
||||
* prefix 5 = stat using subtopic or RESULT
|
||||
* prefix 6 = tele using subtopic or RESULT
|
||||
*/
|
||||
char romram[16];
|
||||
char romram[33];
|
||||
char stopic[TOPSZ];
|
||||
|
||||
snprintf_P(romram, sizeof(romram), ((prefix > 3) && !Settings.flag.mqtt_response) ? S_RSLT_RESULT : subtopic);
|
||||
@ -414,24 +431,24 @@ void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic)
|
||||
void MqttPublishPowerState(byte device)
|
||||
{
|
||||
char stopic[TOPSZ];
|
||||
char scommand[16];
|
||||
char scommand[33];
|
||||
|
||||
if ((device < 1) || (device > devices_present)) {
|
||||
device = 1;
|
||||
}
|
||||
GetPowerDevice(scommand, device, sizeof(scommand));
|
||||
GetTopic_P(stopic, 1, Settings.mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
|
||||
GetTopic_P(stopic, STAT, Settings.mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1)));
|
||||
MqttPublish(stopic);
|
||||
|
||||
GetTopic_P(stopic, 1, Settings.mqtt_topic, scommand);
|
||||
GetTopic_P(stopic, STAT, Settings.mqtt_topic, scommand);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), GetStateText(bitRead(power, device -1)));
|
||||
MqttPublish(stopic, Settings.flag.mqtt_power_retain);
|
||||
}
|
||||
|
||||
void MqttPublishPowerBlinkState(byte device)
|
||||
{
|
||||
char scommand[16];
|
||||
char scommand[33];
|
||||
|
||||
if ((device < 1) || (device > devices_present)) {
|
||||
device = 1;
|
||||
@ -439,7 +456,7 @@ void MqttPublishPowerBlinkState(byte device)
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"" D_JSON_BLINK " %s\"}"),
|
||||
GetPowerDevice(scommand, device, sizeof(scommand)), GetStateText(bitRead(blink_mask, device -1)));
|
||||
|
||||
MqttPublishPrefixTopic_P(5, S_RSLT_POWER);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, S_RSLT_POWER);
|
||||
}
|
||||
|
||||
void MqttConnected()
|
||||
@ -450,15 +467,15 @@ void MqttConnected()
|
||||
|
||||
// Satisfy iobroker (#299)
|
||||
mqtt_data[0] = '\0';
|
||||
MqttPublishPrefixTopic_P(0, S_RSLT_POWER);
|
||||
MqttPublishPrefixTopic_P(CMND, S_RSLT_POWER);
|
||||
|
||||
GetTopic_P(stopic, 0, Settings.mqtt_topic, PSTR("#"));
|
||||
GetTopic_P(stopic, CMND, Settings.mqtt_topic, PSTR("#"));
|
||||
MqttSubscribe(stopic);
|
||||
if (strstr(Settings.mqtt_fulltopic, MQTT_TOKEN_TOPIC) != NULL) {
|
||||
GetTopic_P(stopic, 0, Settings.mqtt_grptopic, PSTR("#"));
|
||||
GetTopic_P(stopic, CMND, Settings.mqtt_grptopic, PSTR("#"));
|
||||
MqttSubscribe(stopic);
|
||||
fallback_topic_flag = 1;
|
||||
GetTopic_P(stopic, 0, mqtt_client, PSTR("#"));
|
||||
GetTopic_P(stopic, CMND, mqtt_client, PSTR("#"));
|
||||
fallback_topic_flag = 0;
|
||||
MqttSubscribe(stopic);
|
||||
}
|
||||
@ -467,26 +484,25 @@ void MqttConnected()
|
||||
}
|
||||
|
||||
if (mqtt_connection_flag) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"" VERSION_STRING "\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"),
|
||||
my_module.name, mqtt_client, Settings.mqtt_grptopic);
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_INFO "1"));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_VERSION "\":\"%s\",\"" D_JSON_FALLBACKTOPIC "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\"}"),
|
||||
my_module.name, my_version, mqtt_client, Settings.mqtt_grptopic);
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "1"));
|
||||
#ifdef USE_WEBSERVER
|
||||
if (Settings.webserver) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"),
|
||||
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_INFO "2"));
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"));
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"),
|
||||
(GetResetReason() == "Exception") ? ESP.getResetInfo().c_str() : GetResetReason().c_str());
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_INFO "3"));
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3"));
|
||||
if (Settings.tele_period) {
|
||||
tele_period = Settings.tele_period -9;
|
||||
}
|
||||
status_update_timer = 2;
|
||||
#ifdef USE_DOMOTICZ
|
||||
DomoticzSetUpdateTimer(2);
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
XdrvCall(FUNC_MQTT_INIT);
|
||||
}
|
||||
mqtt_connection_flag = 0;
|
||||
}
|
||||
@ -539,7 +555,7 @@ void MqttReconnect()
|
||||
#endif // USE_MQTT_TLS
|
||||
MqttClient.setServer(Settings.mqtt_host, Settings.mqtt_port);
|
||||
|
||||
GetTopic_P(stopic, 2, Settings.mqtt_topic, S_LWT);
|
||||
GetTopic_P(stopic, TELE, Settings.mqtt_topic, S_LWT);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_OFFLINE);
|
||||
|
||||
char *mqtt_user = NULL;
|
||||
@ -570,7 +586,6 @@ boolean MqttCommand(boolean grpflg, char *type, uint16_t index, char *dataBuf, u
|
||||
char command [CMDSZ];
|
||||
boolean serviced = true;
|
||||
char stemp1[TOPSZ];
|
||||
char stemp2[10];
|
||||
char scommand[CMDSZ];
|
||||
uint16_t i;
|
||||
|
||||
@ -646,7 +661,7 @@ boolean MqttCommand(boolean grpflg, char *type, uint16_t index, char *dataBuf, u
|
||||
strlcpy(stemp1, (1 == payload) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1));
|
||||
if (strcmp(stemp1, Settings.mqtt_fulltopic)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
||||
strlcpy(Settings.mqtt_fulltopic, stemp1, sizeof(Settings.mqtt_fulltopic));
|
||||
restart_flag = 2;
|
||||
}
|
||||
@ -682,7 +697,7 @@ boolean MqttCommand(boolean grpflg, char *type, uint16_t index, char *dataBuf, u
|
||||
strlcpy(stemp1, (1 == payload) ? MQTT_TOPIC : dataBuf, sizeof(stemp1));
|
||||
if (strcmp(stemp1, Settings.mqtt_topic)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
|
||||
strlcpy(Settings.mqtt_topic, stemp1, sizeof(Settings.mqtt_topic));
|
||||
restart_flag = 2;
|
||||
}
|
||||
@ -737,7 +752,7 @@ boolean MqttCommand(boolean grpflg, char *type, uint16_t index, char *dataBuf, u
|
||||
if ((payload >= 0) && (payload <= 1)) {
|
||||
if (!payload) {
|
||||
for(i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker
|
||||
GetTopic_P(stemp1, 1, Settings.mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand)));
|
||||
GetTopic_P(stemp1, STAT, Settings.mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand)));
|
||||
mqtt_data[0] = '\0';
|
||||
MqttPublish(stemp1, Settings.flag.mqtt_power_retain);
|
||||
}
|
||||
@ -750,8 +765,8 @@ boolean MqttCommand(boolean grpflg, char *type, uint16_t index, char *dataBuf, u
|
||||
if ((payload >= 0) && (payload <= 1)) {
|
||||
if (!payload) {
|
||||
mqtt_data[0] = '\0';
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
|
||||
}
|
||||
Settings.flag.mqtt_sensor_retain = payload;
|
||||
}
|
||||
@ -784,9 +799,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
char command [CMDSZ];
|
||||
char stemp1[TOPSZ];
|
||||
char *p;
|
||||
char *mtopic = NULL;
|
||||
char *type = NULL;
|
||||
byte otype = 0;
|
||||
byte ptype = 0;
|
||||
byte jsflg = 0;
|
||||
byte lines = 1;
|
||||
@ -917,18 +930,23 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
fallback_topic_flag = 0;
|
||||
return;
|
||||
}
|
||||
else if (CMND_STATE == command_code) {
|
||||
mqtt_data[0] = '\0';
|
||||
MqttShowState();
|
||||
}
|
||||
else if ((CMND_POWERONSTATE == command_code) && (Settings.module != MOTOR)) {
|
||||
/* 0 = Keep relays off after power on
|
||||
* 1 = Turn relays on after power on
|
||||
* 1 = Turn relays on after power on, if PulseTime set wait for PulseTime seconds, and turn relays off
|
||||
* 2 = Toggle relays after power on
|
||||
* 3 = Set relays to last saved state after power on
|
||||
* 4 = Turn relays on and disable any relay control (used for Sonoff Pow to always measure power)
|
||||
* 5 = Keep relays off after power on, if PulseTime set wait for PulseTime seconds, and turn relays on
|
||||
*/
|
||||
if ((payload >= 0) && (payload <= 4)) {
|
||||
if ((payload >= POWER_ALL_OFF) && (payload <= POWER_ALL_OFF_PULSETIME_ON)) {
|
||||
Settings.poweronstate = payload;
|
||||
if (4 == Settings.poweronstate) {
|
||||
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
|
||||
for (byte i = 1; i <= devices_present; i++) {
|
||||
ExecuteCommandPower(i, 1);
|
||||
ExecuteCommandPower(i, POWER_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -970,7 +988,18 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, (Settings.save_data > 1) ? stemp1 : GetStateText(Settings.save_data));
|
||||
}
|
||||
else if ((CMND_SETOPTION == command_code) && ((index >= 0) && (index <= 18)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) {
|
||||
else if (CMND_SENSOR == command_code) {
|
||||
XdrvMailbox.topic = command;
|
||||
XdrvMailbox.index = index;
|
||||
XdrvMailbox.payload = payload;
|
||||
XdrvMailbox.data_len = data_len;
|
||||
XdrvMailbox.data = dataBuf;
|
||||
XsnsCall(FUNC_COMMAND);
|
||||
// if (!XsnsCall(FUNC_COMMAND)) {
|
||||
// type = NULL;
|
||||
// }
|
||||
}
|
||||
else if ((CMND_SETOPTION == command_code) && ((index <= 21) || ((index > 31) && (index <= P_MAX_PARAM8 + 31)))) {
|
||||
if (index <= 31) {
|
||||
ptype = 0; // SetOption0 .. 31
|
||||
} else {
|
||||
@ -983,6 +1012,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
switch (index) {
|
||||
case 3: // mqtt
|
||||
case 15: // pwm_control
|
||||
case 19: // hass_discovery
|
||||
restart_flag = 2;
|
||||
case 0: // save_state
|
||||
case 1: // button_restrict
|
||||
@ -997,6 +1027,8 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
case 16: // ws_clock_reverse
|
||||
case 17: // decimal_text
|
||||
case 18: // light_signal
|
||||
case 20: // not_power_linked
|
||||
case 21: // no_power_on_check
|
||||
bitWrite(Settings.flag.data, index, payload);
|
||||
}
|
||||
if (12 == index) { // stop_flash_rotate
|
||||
@ -1092,9 +1124,9 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
jsflg = 1;
|
||||
snprintf_P(stemp1, sizeof(stemp1), kModules[i].name);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i +1, stemp1);
|
||||
if ((strlen(mqtt_data) > 300) || (i == MAXMODULE -1)) {
|
||||
if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == MAXMODULE -1)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]}"), mqtt_data);
|
||||
MqttPublishPrefixTopic_P(5, type);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, type);
|
||||
jsflg = 0;
|
||||
lines++;
|
||||
}
|
||||
@ -1121,8 +1153,8 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||
}
|
||||
jsflg = 1;
|
||||
snprintf_P(stemp1, sizeof(stemp1), kSensors[Settings.my_gp.io[i]]);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":\"%d (%s)\""), mqtt_data, i, Settings.my_gp.io[i], stemp1);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":\"%d (%s)\""),
|
||||
mqtt_data, i, Settings.my_gp.io[i], GetTextIndexed(stemp1, sizeof(stemp1), Settings.my_gp.io[i], kSensorNames));
|
||||
}
|
||||
}
|
||||
if (jsflg) {
|
||||
@ -1139,18 +1171,17 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||
}
|
||||
jsflg = 1;
|
||||
snprintf_P(stemp1, sizeof(stemp1), kSensors[i]);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i, stemp1);
|
||||
if ((strlen(mqtt_data) > 300) || (i == GPIO_SENSOR_END -1)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i, GetTextIndexed(stemp1, sizeof(stemp1), i, kSensorNames));
|
||||
if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == GPIO_SENSOR_END -1)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]}"), mqtt_data);
|
||||
MqttPublishPrefixTopic_P(5, type);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, type);
|
||||
jsflg = 0;
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
mqtt_data[0] = '\0';
|
||||
}
|
||||
else if ((CMND_PWM == command_code) && !light_type && (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)) {
|
||||
Settings.pwm_value[index -1] = payload;
|
||||
analogWrite(pin[GPIO_PWM1 + index -1], bitRead(pwm_inverted, index -1) ? Settings.pwm_range - payload : payload);
|
||||
@ -1175,7 +1206,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
else if (CMND_PWMRANGE == command_code) {
|
||||
if ((1 == payload) || ((payload > 254) && (payload < 1024))) {
|
||||
Settings.pwm_range = (1 == payload) ? PWM_RANGE : payload;
|
||||
for (byte i; i < MAX_PWMS; i++) {
|
||||
for (byte i = 0; i < MAX_PWMS; i++) {
|
||||
if (Settings.pwm_value[i] > Settings.pwm_range) {
|
||||
Settings.pwm_value[i] = Settings.pwm_range;
|
||||
}
|
||||
@ -1189,7 +1220,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
RtcSettings.pulse_counter[index -1] = payload16;
|
||||
Settings.pulse_counter[index -1] = payload16;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, index, RtcSettings.pulse_counter[index -1]);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_LVALUE, command, index, RtcSettings.pulse_counter[index -1]);
|
||||
}
|
||||
else if ((CMND_COUNTERTYPE == command_code) && (index > 0) && (index <= MAX_COUNTERS)) {
|
||||
if ((payload >= 0) && (payload <= 1) && (pin[GPIO_CNTR1 + index -1] < 99)) {
|
||||
@ -1222,9 +1253,9 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
// We also need at least 3 chars to make a valid version number string.
|
||||
if (((1 == data_len) && (1 == payload)) || ((data_len >= 3) && NewerVersion(dataBuf))) {
|
||||
ota_state_flag = 3;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_VERSION " " VERSION_STRING " " D_JSON_FROM " %s\"}", command, Settings.ota_url);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}", command, my_version, Settings.ota_url);
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_ONE_OR_GT "\"}", command, VERSION_STRING);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_ONE_OR_GT "\"}", command, my_version);
|
||||
}
|
||||
}
|
||||
else if (CMND_OTAURL == command_code) {
|
||||
@ -1471,15 +1502,6 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
I2cScan(mqtt_data, sizeof(mqtt_data));
|
||||
}
|
||||
#endif // USE_I2C
|
||||
#ifdef USE_INA219
|
||||
else if (CMND_INA219MODE == command_code) {
|
||||
if ((payload >= 0) && (payload <= 2)) {
|
||||
Settings.ina219_mode = payload;
|
||||
restart_flag = 2;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.ina219_mode);
|
||||
}
|
||||
#endif // USE_INA219
|
||||
else if (Settings.flag.mqtt_enabled && MqttCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) {
|
||||
// Serviced
|
||||
}
|
||||
@ -1505,7 +1527,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
||||
type = (char*)topicBuf;
|
||||
}
|
||||
if (mqtt_data[0] != '\0') {
|
||||
MqttPublishPrefixTopic_P(5, type);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, type);
|
||||
}
|
||||
fallback_topic_flag = 0;
|
||||
}
|
||||
@ -1524,7 +1546,6 @@ boolean send_button_power(byte key, byte device, byte state)
|
||||
|
||||
char stopic[TOPSZ];
|
||||
char scommand[CMDSZ];
|
||||
char stemp1[10];
|
||||
boolean result = false;
|
||||
|
||||
char *key_topic = (key) ? Settings.switch_topic : Settings.button_topic;
|
||||
@ -1532,7 +1553,7 @@ boolean send_button_power(byte key, byte device, byte state)
|
||||
if (!key && (device > devices_present)) {
|
||||
device = 1;
|
||||
}
|
||||
GetTopic_P(stopic, 0, key_topic, GetPowerDevice(scommand, device, sizeof(scommand), key));
|
||||
GetTopic_P(stopic, CMND, key_topic, GetPowerDevice(scommand, device, sizeof(scommand), key));
|
||||
if (9 == state) {
|
||||
mqtt_data[0] = '\0';
|
||||
} else {
|
||||
@ -1566,7 +1587,7 @@ void ExecuteCommandPower(byte device, byte state)
|
||||
// state 9 = Show power state
|
||||
|
||||
uint8_t publish_power = 1;
|
||||
if ((6 == state) || (7 == state)) {
|
||||
if ((POWER_OFF_NO_STATE == state) || (POWER_ON_NO_STATE == state)) {
|
||||
state &= 1;
|
||||
publish_power = 0;
|
||||
}
|
||||
@ -1577,7 +1598,7 @@ void ExecuteCommandPower(byte device, byte state)
|
||||
pulse_timer[(device -1)] = 0;
|
||||
}
|
||||
power_t mask = 1 << (device -1);
|
||||
if (state <= 2) {
|
||||
if (state <= POWER_TOGGLE) {
|
||||
if ((blink_mask & mask)) {
|
||||
blink_mask &= (POWER_MASK ^ mask); // Clear device mask
|
||||
MqttPublishPowerBlinkState(device);
|
||||
@ -1587,19 +1608,19 @@ void ExecuteCommandPower(byte device, byte state)
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
power_t imask = 1 << i;
|
||||
if ((power & imask) && (mask != imask)) {
|
||||
ExecuteCommandPower(i +1, 0);
|
||||
ExecuteCommandPower(i +1, POWER_OFF);
|
||||
}
|
||||
}
|
||||
interlock_mutex = 0;
|
||||
}
|
||||
switch (state) {
|
||||
case 0: { // Off
|
||||
case POWER_OFF: {
|
||||
power &= (POWER_MASK ^ mask);
|
||||
break; }
|
||||
case 1: // On
|
||||
case POWER_ON:
|
||||
power |= mask;
|
||||
break;
|
||||
case 2: // Toggle
|
||||
case POWER_TOGGLE:
|
||||
power ^= mask;
|
||||
}
|
||||
SetDevicePower(power);
|
||||
@ -1607,10 +1628,11 @@ void ExecuteCommandPower(byte device, byte state)
|
||||
DomoticzUpdatePowerState(device);
|
||||
#endif // USE_DOMOTICZ
|
||||
if (device <= MAX_PULSETIMERS) {
|
||||
pulse_timer[(device -1)] = (power & mask) ? Settings.pulse_timer[(device -1)] : 0;
|
||||
// pulse_timer[(device -1)] = (power & mask) ? Settings.pulse_timer[(device -1)] : 0;
|
||||
pulse_timer[(device -1)] = (((POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate) ? ~power : power) & mask) ? Settings.pulse_timer[(device -1)] : 0;
|
||||
}
|
||||
}
|
||||
else if (3 == state) { // Blink
|
||||
else if (POWER_BLINK == state) {
|
||||
if (!(blink_mask & mask)) {
|
||||
blink_powersave = (blink_powersave & (POWER_MASK ^ mask)) | (power & mask); // Save state
|
||||
blink_power = (power >> (device -1))&1; // Prep to Toggle
|
||||
@ -1621,7 +1643,7 @@ void ExecuteCommandPower(byte device, byte state)
|
||||
MqttPublishPowerBlinkState(device);
|
||||
return;
|
||||
}
|
||||
else if (4 == state) { // No Blink
|
||||
else if (POWER_BLINK_STOP == state) {
|
||||
byte flag = (blink_mask & mask);
|
||||
blink_mask &= (POWER_MASK ^ mask); // Clear device mask
|
||||
MqttPublishPowerBlinkState(device);
|
||||
@ -1693,14 +1715,14 @@ void PublishStatus(uint8_t 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_UPTIME "\":%d,\"" D_CMND_SLEEP "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
||||
baudrate, Settings.mqtt_grptopic, Settings.ota_url, uptime, Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
||||
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_UPTIME "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
||||
baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetUptime().c_str(), Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
||||
}
|
||||
|
||||
if ((0 == payload) || (2 == payload)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_JSON_VERSION "\":\"" VERSION_STRING "\",\"" D_JSON_BUILDDATETIME "\":\"%s\",\"" D_JSON_BOOTVERSION "\":%d,\"" D_JSON_COREVERSION "\":\"" ARDUINO_ESP8266_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\"}}"),
|
||||
GetBuildDateAndTime().c_str(), ESP.getBootVersion(), ESP.getSdkVersion());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_JSON_VERSION "\":\"%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\",\"" D_JSON_BOOTVERSION "\":%d,\"" D_JSON_COREVERSION "\":\"" ARDUINO_ESP8266_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\"}}"),
|
||||
my_version, GetBuildDateAndTime().c_str(), ESP.getBootVersion(), ESP.getSdkVersion());
|
||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2"));
|
||||
}
|
||||
|
||||
@ -1765,16 +1787,22 @@ void PublishStatus(uint8_t payload)
|
||||
|
||||
void MqttShowState()
|
||||
{
|
||||
char stemp1[16];
|
||||
char stemp1[33];
|
||||
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":%d"), mqtt_data, GetDateAndTime().c_str(), uptime);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\""), mqtt_data, GetDateAndTime().c_str(), GetUptime().c_str());
|
||||
#ifdef USE_ADC_VCC
|
||||
dtostrfd((double)ESP.getVcc()/1000, 3, stemp1);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1);
|
||||
#endif
|
||||
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":\"%s\""), mqtt_data, GetPowerDevice(stemp1, i +1, sizeof(stemp1)), GetStateText(bitRead(power, i)));
|
||||
if (i == light_device -1) {
|
||||
LightState(1);
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":\"%s\""), mqtt_data, GetPowerDevice(stemp1, i +1, sizeof(stemp1)), GetStateText(bitRead(power, i)));
|
||||
}
|
||||
}
|
||||
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_RSSI "\":%d,\"" D_JSON_APMAC_ADDRESS "\":\"%s\"}}"),
|
||||
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
|
||||
}
|
||||
@ -1791,7 +1819,7 @@ boolean MqttShowSensor()
|
||||
}
|
||||
XsnsCall(FUNC_JSON_APPEND);
|
||||
boolean json_data_available = (strlen(mqtt_data) - json_data_start);
|
||||
if (strstr_P(mqtt_data, PSTR(D_TEMPERATURE))) {
|
||||
if (strstr_P(mqtt_data, PSTR(D_JSON_TEMPERATURE))) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_TEMPERATURE_UNIT "\":\"%c\""), mqtt_data, TempUnit());
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
@ -1806,6 +1834,8 @@ boolean MqttShowSensor()
|
||||
|
||||
void PerformEverySecond()
|
||||
{
|
||||
uptime++;
|
||||
|
||||
if (blockgpio0) {
|
||||
blockgpio0--;
|
||||
}
|
||||
@ -1855,11 +1885,11 @@ void PerformEverySecond()
|
||||
|
||||
mqtt_data[0] = '\0';
|
||||
MqttShowState();
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_STATE));
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE));
|
||||
|
||||
mqtt_data[0] = '\0';
|
||||
if (MqttShowSensor()) {
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1870,9 +1900,8 @@ void PerformEverySecond()
|
||||
|
||||
if ((2 == RtcTime.minute) && latest_uptime_flag) {
|
||||
latest_uptime_flag = false;
|
||||
uptime++;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":%d}"), GetDateAndTime().c_str(), uptime);
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_UPTIME));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\"}"), GetDateAndTime().c_str(), GetUptime().c_str());
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_UPTIME));
|
||||
}
|
||||
if ((3 == RtcTime.minute) && !latest_uptime_flag) {
|
||||
latest_uptime_flag = true;
|
||||
@ -1890,129 +1919,130 @@ void ButtonHandler()
|
||||
char scmnd[20];
|
||||
|
||||
uint8_t maxdev = (devices_present > MAX_KEYS) ? MAX_KEYS : devices_present;
|
||||
for (byte i = 0; i < maxdev; i++) {
|
||||
for (byte button_index = 0; button_index < maxdev; button_index++) {
|
||||
button = NOT_PRESSED;
|
||||
button_present = 0;
|
||||
|
||||
if (!i && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) {
|
||||
if (!button_index && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) {
|
||||
button_present = 1;
|
||||
if (dual_button_code) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), dual_button_code);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
button = PRESSED;
|
||||
if (0xF500 == dual_button_code) { // Button hold
|
||||
holdbutton[i] = (Settings.param[P_HOLD_TIME] * (STATES / 10)) -1;
|
||||
holdbutton[button_index] = (Settings.param[P_HOLD_TIME] * (STATES / 10)) -1;
|
||||
}
|
||||
dual_button_code = 0;
|
||||
}
|
||||
} else {
|
||||
if ((pin[GPIO_KEY1 +i] < 99) && !blockgpio0) {
|
||||
if ((pin[GPIO_KEY1 +button_index] < 99) && !blockgpio0) {
|
||||
button_present = 1;
|
||||
button = digitalRead(pin[GPIO_KEY1 +i]);
|
||||
button = digitalRead(pin[GPIO_KEY1 +button_index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (button_present) {
|
||||
if (SONOFF_4CHPRO == Settings.module) {
|
||||
if (holdbutton[i]) {
|
||||
holdbutton[i]--;
|
||||
if (holdbutton[button_index]) {
|
||||
holdbutton[button_index]--;
|
||||
}
|
||||
|
||||
boolean button_pressed = false;
|
||||
if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_10), i +1);
|
||||
if ((PRESSED == button) && (NOT_PRESSED == lastbutton[button_index])) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_LEVEL_10), button_index +1);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
holdbutton[i] = STATES;
|
||||
holdbutton[button_index] = STATES;
|
||||
button_pressed = true;
|
||||
}
|
||||
if ((NOT_PRESSED == button) && (PRESSED == lastbutton[i])) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_01), i +1);
|
||||
if ((NOT_PRESSED == button) && (PRESSED == lastbutton[button_index])) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_LEVEL_01), button_index +1);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
if (!holdbutton[i]) { // Do not allow within 1 second
|
||||
if (!holdbutton[button_index]) { // Do not allow within 1 second
|
||||
button_pressed = true;
|
||||
}
|
||||
}
|
||||
if (button_pressed) {
|
||||
if (!send_button_power(0, i +1, 2)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(i +1, 2); // Execute Toggle command internally
|
||||
if (!send_button_power(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(button_index +1, POWER_TOGGLE); // Execute Toggle command internally
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) {
|
||||
if ((PRESSED == button) && (NOT_PRESSED == lastbutton[button_index])) {
|
||||
if (Settings.flag.button_single) { // Allow only single button press for immediate action
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_IMMEDIATE), i +1);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
if (!send_button_power(0, i +1, 2)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(i +1, 2); // Execute Toggle command internally
|
||||
if (!send_button_power(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(button_index +1, POWER_TOGGLE); // Execute Toggle command internally
|
||||
}
|
||||
} else {
|
||||
multipress[i] = (multiwindow[i]) ? multipress[i] +1 : 1;
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_MULTI_PRESS " %d"), i +1, multipress[i]);
|
||||
multipress[button_index] = (multiwindow[button_index]) ? multipress[button_index] +1 : 1;
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_MULTI_PRESS " %d"), button_index +1, multipress[button_index]);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
multiwindow[i] = STATES /2; // 0.5 second multi press window
|
||||
multiwindow[button_index] = STATES /2; // 0.5 second multi press window
|
||||
}
|
||||
blinks = 201;
|
||||
}
|
||||
|
||||
if (NOT_PRESSED == button) {
|
||||
holdbutton[i] = 0;
|
||||
holdbutton[button_index] = 0;
|
||||
} else {
|
||||
holdbutton[i]++;
|
||||
holdbutton[button_index]++;
|
||||
if (Settings.flag.button_single) { // Allow only single button press for immediate action
|
||||
if (holdbutton[i] == Settings.param[P_HOLD_TIME] * (STATES / 10) * 4) { // Button hold for four times longer
|
||||
if (holdbutton[button_index] == Settings.param[P_HOLD_TIME] * (STATES / 10) * 4) { // Button hold for four times longer
|
||||
// Settings.flag.button_single = 0;
|
||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only
|
||||
ExecuteCommand(scmnd);
|
||||
}
|
||||
} else {
|
||||
if (holdbutton[i] == Settings.param[P_HOLD_TIME] * (STATES / 10)) { // Button hold
|
||||
multipress[i] = 0;
|
||||
if (holdbutton[button_index] == Settings.param[P_HOLD_TIME] * (STATES / 10)) { // Button hold
|
||||
multipress[button_index] = 0;
|
||||
if (!Settings.flag.button_restrict) { // No button restriction
|
||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1"));
|
||||
ExecuteCommand(scmnd);
|
||||
} else {
|
||||
send_button_power(0, i +1, 3); // Execute Hold command via MQTT if ButtonTopic is set
|
||||
send_button_power(0, button_index +1, 3); // Execute Hold command via MQTT if ButtonTopic is set
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Settings.flag.button_single) { // Allow multi-press
|
||||
if (multiwindow[i]) {
|
||||
multiwindow[i]--;
|
||||
if (multiwindow[button_index]) {
|
||||
multiwindow[button_index]--;
|
||||
} else {
|
||||
if (!restart_flag && !holdbutton[i] && (multipress[i] > 0) && (multipress[i] < MAX_BUTTON_COMMANDS +3)) {
|
||||
if (!restart_flag && !holdbutton[button_index] && (multipress[button_index] > 0) && (multipress[button_index] < MAX_BUTTON_COMMANDS +3)) {
|
||||
boolean single_press = false;
|
||||
if (multipress[i] < 3) { // Single or Double press
|
||||
if (multipress[button_index] < 3) { // Single or Double press
|
||||
if ((SONOFF_DUAL_R2 == Settings.module) || (SONOFF_DUAL == Settings.module) || (CH4 == Settings.module)) {
|
||||
single_press = true;
|
||||
} else {
|
||||
single_press = (Settings.flag.button_swap +1 == multipress[i]);
|
||||
multipress[i] = 1;
|
||||
single_press = (Settings.flag.button_swap +1 == multipress[button_index]);
|
||||
multipress[button_index] = 1;
|
||||
}
|
||||
}
|
||||
if (single_press && send_button_power(0, i + multipress[i], 2)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
if (single_press && send_button_power(0, button_index + multipress[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
// Success
|
||||
} else {
|
||||
if (multipress[i] < 3) { // Single or Double press
|
||||
if (multipress[button_index] < 3) { // Single or Double press
|
||||
if (WifiState()) { // WPSconfig, Smartconfig or Wifimanager active
|
||||
restart_flag = 1;
|
||||
} else {
|
||||
ExecuteCommandPower(i + multipress[i], 2); // Execute Toggle command internally
|
||||
ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE); // Execute Toggle command internally
|
||||
}
|
||||
} else { // 3 - 7 press
|
||||
if (!Settings.flag.button_restrict) {
|
||||
snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[i] -3]);
|
||||
snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]);
|
||||
ExecuteCommand(scmnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
multipress[i] = 0;
|
||||
multipress[button_index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lastbutton[i] = button;
|
||||
lastbutton[button_index] = button;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2085,7 +2115,7 @@ void SwitchHandler()
|
||||
|
||||
if (switchflag < 3) {
|
||||
if (!send_button_power(1, i +1, switchflag)) { // Execute command via MQTT
|
||||
ExecuteCommandPower(i +1, switchflag); // Execute command internally (if i < devices_present)
|
||||
ExecuteCommandPower(i +1, switchflag); // Execute command internally (if i < devices_present)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2136,7 +2166,8 @@ void StateLoop()
|
||||
if ((pulse_timer[i] > 0) && (pulse_timer[i] < 112)) {
|
||||
pulse_timer[i]--;
|
||||
if (!pulse_timer[i]) {
|
||||
ExecuteCommandPower(i +1, 0);
|
||||
// ExecuteCommandPower(i +1, POWER_OFF);
|
||||
ExecuteCommandPower(i +1, (POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate) ? POWER_ON : POWER_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2224,6 +2255,8 @@ void StateLoop()
|
||||
if (ota_state_flag && (backlog_pointer == backlog_index)) {
|
||||
ota_state_flag--;
|
||||
if (2 == ota_state_flag) {
|
||||
ota_url = Settings.ota_url;
|
||||
RtcSettings.ota_loader = 0; // Try requested image first
|
||||
ota_retry_counter = OTA_ATTEMPTS;
|
||||
ESPhttpUpdate.rebootOnUpdate(false);
|
||||
SettingsSave(1); // Free flash for OTA update
|
||||
@ -2241,10 +2274,32 @@ void StateLoop()
|
||||
ota_result = 0;
|
||||
ota_retry_counter--;
|
||||
if (ota_retry_counter) {
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR("OTA: Attempt %d"), OTA_ATTEMPTS - ota_retry_counter);
|
||||
// AddLog(LOG_LEVEL_INFO);
|
||||
ota_result = (HTTP_UPDATE_FAILED != ESPhttpUpdate.update(Settings.ota_url));
|
||||
#ifndef BE_MINIMAL
|
||||
if (RtcSettings.ota_loader) {
|
||||
char *pch = strrchr(Settings.ota_url, '-'); // Change from filename-DE.bin into filename-minimal.bin
|
||||
char *ech = strrchr(Settings.ota_url, '.'); // Change from filename.bin into filename-minimal.bin
|
||||
if (!pch) {
|
||||
pch = ech;
|
||||
}
|
||||
if (pch) {
|
||||
strlcpy(mqtt_data, Settings.ota_url, pch - Settings.ota_url +1);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s-" D_JSON_MINIMAL "%s"), mqtt_data, ech); // Minimal filename must be filename-minimal
|
||||
ota_url = mqtt_data; // Try minimal image
|
||||
}
|
||||
}
|
||||
#endif // BE_MINIMAL
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "%s"), ota_url);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
ota_result = (HTTP_UPDATE_FAILED != ESPhttpUpdate.update(ota_url));
|
||||
if (!ota_result) {
|
||||
#ifndef BE_MINIMAL
|
||||
int ota_error = ESPhttpUpdate.getLastError();
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Ota error %d"), ota_error);
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
if ((HTTP_UE_TOO_LESS_SPACE == ota_error) || (HTTP_UE_BIN_FOR_WRONG_FLASH == ota_error)) {
|
||||
RtcSettings.ota_loader = 1; // Try minimal image next
|
||||
}
|
||||
#endif // BE_MINIMAL
|
||||
ota_state_flag = 2; // Upgrade failed - retry
|
||||
}
|
||||
}
|
||||
@ -2258,7 +2313,7 @@ void StateLoop()
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_JSON_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str());
|
||||
}
|
||||
restart_flag = 2; // Restart anyway to keep memory clean webserver
|
||||
MqttPublishPrefixTopic_P(1, PSTR(D_CMND_UPGRADE));
|
||||
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_UPGRADE));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2368,6 +2423,17 @@ void SerialInput()
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Sonoff S31 4800 baud serial interface
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
if (SONOFF_S31 == Settings.module) {
|
||||
if (CseSerialInput()) {
|
||||
serial_in_byte_counter = 0;
|
||||
Serial.flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
if (serial_in_byte > 127) { // binary data...
|
||||
@ -2398,7 +2464,7 @@ void SerialInput()
|
||||
|
||||
else if (serial_in_byte == '\n') {
|
||||
serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed
|
||||
seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? LOG_LEVEL_INFO : Settings.seriallog_level;
|
||||
seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (byte)LOG_LEVEL_INFO : Settings.seriallog_level;
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), serial_in_buffer);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
ExecuteCommand(serial_in_buffer);
|
||||
@ -2579,6 +2645,7 @@ void GpioInit()
|
||||
if (!light_type) {
|
||||
for (byte i = 0; i < MAX_PWMS; i++) { // Basic PWM control only
|
||||
if (pin[GPIO_PWM1 +i] < 99) {
|
||||
pwm_present = true;
|
||||
pinMode(pin[GPIO_PWM1 +i], OUTPUT);
|
||||
analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]);
|
||||
}
|
||||
@ -2591,7 +2658,7 @@ void GpioInit()
|
||||
}
|
||||
SetLedPower(Settings.ledstate &8);
|
||||
|
||||
XDrvInit();
|
||||
XdrvCall(FUNC_INIT);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
@ -2607,6 +2674,16 @@ void setup()
|
||||
Serial.println();
|
||||
seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded
|
||||
|
||||
snprintf_P(my_version, sizeof(my_version), PSTR("%d.%d.%d"), VERSION >> 24 & 0xff, VERSION >> 16 & 0xff, VERSION >> 8 & 0xff);
|
||||
if (VERSION & 0x1f) {
|
||||
idx = strlen(my_version);
|
||||
my_version[idx] = 96 + (VERSION & 0x1f);
|
||||
my_version[idx +1] = 0;
|
||||
}
|
||||
#ifdef BE_MINIMAL
|
||||
snprintf_P(my_version, sizeof(my_version), PSTR("%s-" D_JSON_MINIMAL), my_version);
|
||||
#endif // BE_MINIMAL
|
||||
|
||||
SettingsLoad();
|
||||
SettingsDelta();
|
||||
|
||||
@ -2641,28 +2718,29 @@ void setup()
|
||||
GetMqttClient(mqtt_client, Settings.mqtt_client, sizeof(mqtt_client));
|
||||
|
||||
if (MOTOR == Settings.module) {
|
||||
Settings.poweronstate = 1; // Needs always on else in limbo!
|
||||
Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo!
|
||||
}
|
||||
if (4 == Settings.poweronstate) { // Allways on
|
||||
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
|
||||
SetDevicePower(1);
|
||||
} else {
|
||||
if ((resetInfo.reason == REASON_DEFAULT_RST) || (resetInfo.reason == REASON_EXT_SYS_RST)) {
|
||||
switch (Settings.poweronstate) {
|
||||
case 0: // All off
|
||||
case POWER_ALL_OFF:
|
||||
case POWER_ALL_OFF_PULSETIME_ON:
|
||||
power = 0;
|
||||
SetDevicePower(power);
|
||||
break;
|
||||
case 1: // All on
|
||||
case POWER_ALL_ON: // All on
|
||||
power = (1 << devices_present) -1;
|
||||
SetDevicePower(power);
|
||||
break;
|
||||
case 2: // All saved state toggle
|
||||
power = Settings.power & ((1 << devices_present) -1) ^ POWER_MASK;
|
||||
case POWER_ALL_SAVED_TOGGLE:
|
||||
power = (Settings.power & ((1 << devices_present) -1)) ^ POWER_MASK;
|
||||
if (Settings.flag.save_state) {
|
||||
SetDevicePower(power);
|
||||
}
|
||||
break;
|
||||
case 3: // All saved state
|
||||
case POWER_ALL_SAVED:
|
||||
power = Settings.power & ((1 << devices_present) -1);
|
||||
if (Settings.flag.save_state) {
|
||||
SetDevicePower(power);
|
||||
@ -2682,19 +2760,23 @@ void setup()
|
||||
if ((i < MAX_RELAYS) && (pin[GPIO_REL1 +i] < 99)) {
|
||||
bitWrite(power, i, digitalRead(pin[GPIO_REL1 +i]) ^ bitRead(rel_inverted, i));
|
||||
}
|
||||
if ((i < MAX_PULSETIMERS) && bitRead(power, i)) {
|
||||
if ((i < MAX_PULSETIMERS) && (bitRead(power, i) || (POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate))) {
|
||||
pulse_timer[i] = Settings.pulse_timer[i];
|
||||
}
|
||||
}
|
||||
|
||||
blink_powersave = power;
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_PROJECT " %s %s (" D_CMND_TOPIC " %s, " D_FALLBACK " %s, " D_CMND_GROUPTOPIC " %s) " D_VERSION " " VERSION_STRING),
|
||||
PROJECT, Settings.friendlyname[0], Settings.mqtt_topic, mqtt_client, Settings.mqtt_grptopic);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_PROJECT " %s %s (" D_CMND_TOPIC " %s, " D_FALLBACK " %s, " D_CMND_GROUPTOPIC " %s) " D_VERSION " %s"),
|
||||
PROJECT, Settings.friendlyname[0], Settings.mqtt_topic, mqtt_client, Settings.mqtt_grptopic, my_version);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
#ifdef BE_MINIMAL
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_WARNING_MINIMAL_VERSION));
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
#endif // BE_MINIMAL
|
||||
|
||||
RtcInit();
|
||||
XSnsInit();
|
||||
XsnsCall(FUNC_INIT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
||||
@ -52,6 +52,9 @@ void WifiWpsStatusCallback(wps_cb_status status);
|
||||
#ifdef USE_DOMOTICZ
|
||||
#undef USE_DOMOTICZ // Disable Domoticz
|
||||
#endif
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
#undef USE_HOME_ASSISTANT // Disable Home Assistant
|
||||
#endif
|
||||
//#ifdef USE_WEBSERVER
|
||||
//#undef USE_WEBSERVER // Disable Webserver
|
||||
//#endif
|
||||
@ -79,9 +82,21 @@ void WifiWpsStatusCallback(wps_cb_status status);
|
||||
#ifdef USE_DHT
|
||||
#undef USE_DHT // Disable internal DHT sensor
|
||||
#endif
|
||||
#ifdef USE_DISPLAY
|
||||
#undef USE_DISPLAY // Disable Display support
|
||||
#endif
|
||||
#ifdef USE_MHZ19
|
||||
#undef USE_MHZ19 // Disable support for MH-Z19 CO2 sensor
|
||||
#endif
|
||||
#ifdef USE_SENSEAIR
|
||||
#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor
|
||||
#endif
|
||||
#ifdef USE_IR_REMOTE
|
||||
#undef USE_IR_REMOTE // Disable IR driver
|
||||
#endif
|
||||
#ifdef USE_ARILUX_RF
|
||||
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
|
||||
#endif
|
||||
#ifdef DEBUG_THEO
|
||||
#undef DEBUG_THEO // Disable debug code
|
||||
#endif
|
||||
@ -100,10 +115,12 @@ void WifiWpsStatusCallback(wps_cb_status status);
|
||||
#endif
|
||||
|
||||
#ifndef MESSZ
|
||||
#define MESSZ 405 // Max number of characters in JSON message string (6 x DS18x20 sensors)
|
||||
//#define MESSZ 405 // Max number of characters in JSON message string (6 x DS18x20 sensors)
|
||||
//#define MESSZ 893 // Max number of characters in JSON message string (Hass discovery and nice MQTT_MAX_PACKET_SIZE = 1000)
|
||||
#define MESSZ (MQTT_MAX_PACKET_SIZE -TOPSZ -7) // Max number of characters in JSON message string (6 x DS18x20 sensors)
|
||||
#endif
|
||||
|
||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
//#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
#ifndef ARDUINO_ESP8266_RELEASE
|
||||
#define ARDUINO_ESP8266_RELEASE "STAGED"
|
||||
#endif
|
||||
|
||||
@ -86,78 +86,10 @@ enum UserSelectablePins {
|
||||
GPIO_SAIR_RX, // SenseAir Serial interface
|
||||
GPIO_SPI_CS, // SPI Chip Select
|
||||
GPIO_SPI_DC, // SPI Data Direction
|
||||
GPIO_BACKLIGHT,
|
||||
GPIO_BACKLIGHT, // Display backlight control
|
||||
GPIO_PMS5003, // Plantower PMS5003 Serial interface
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
// Text in webpage Module Parameters and commands GPIOS and GPIO
|
||||
const char kSensors[GPIO_SENSOR_END][9] PROGMEM = {
|
||||
D_SENSOR_NONE,
|
||||
D_SENSOR_DHT11,
|
||||
D_SENSOR_AM2301,
|
||||
D_SENSOR_SI7021,
|
||||
D_SENSOR_DS18X20,
|
||||
D_SENSOR_I2C_SCL,
|
||||
D_SENSOR_I2C_SDA,
|
||||
D_SENSOR_WS2812,
|
||||
D_SENSOR_IRSEND,
|
||||
D_SENSOR_SWITCH "1",
|
||||
D_SENSOR_SWITCH "2",
|
||||
D_SENSOR_SWITCH "3",
|
||||
D_SENSOR_SWITCH "4",
|
||||
D_SENSOR_BUTTON "1",
|
||||
D_SENSOR_BUTTON "2",
|
||||
D_SENSOR_BUTTON "3",
|
||||
D_SENSOR_BUTTON "4",
|
||||
D_SENSOR_RELAY "1",
|
||||
D_SENSOR_RELAY "2",
|
||||
D_SENSOR_RELAY "3",
|
||||
D_SENSOR_RELAY "4",
|
||||
D_SENSOR_RELAY "5",
|
||||
D_SENSOR_RELAY "6",
|
||||
D_SENSOR_RELAY "7",
|
||||
D_SENSOR_RELAY "8",
|
||||
D_SENSOR_RELAY "1i",
|
||||
D_SENSOR_RELAY "2i",
|
||||
D_SENSOR_RELAY "3i",
|
||||
D_SENSOR_RELAY "4i",
|
||||
D_SENSOR_RELAY "5i",
|
||||
D_SENSOR_RELAY "6i",
|
||||
D_SENSOR_RELAY "7i",
|
||||
D_SENSOR_RELAY "8i",
|
||||
D_SENSOR_PWM "1",
|
||||
D_SENSOR_PWM "2",
|
||||
D_SENSOR_PWM "3",
|
||||
D_SENSOR_PWM "4",
|
||||
D_SENSOR_PWM "5",
|
||||
D_SENSOR_COUNTER "1",
|
||||
D_SENSOR_COUNTER "2",
|
||||
D_SENSOR_COUNTER "3",
|
||||
D_SENSOR_COUNTER "4",
|
||||
D_SENSOR_PWM "1i",
|
||||
D_SENSOR_PWM "2i",
|
||||
D_SENSOR_PWM "3i",
|
||||
D_SENSOR_PWM "4i",
|
||||
D_SENSOR_PWM "5i",
|
||||
D_SENSOR_IRRECV,
|
||||
D_SENSOR_LED "1",
|
||||
D_SENSOR_LED "2",
|
||||
D_SENSOR_LED "3",
|
||||
D_SENSOR_LED "4",
|
||||
D_SENSOR_LED "1i",
|
||||
D_SENSOR_LED "2i",
|
||||
D_SENSOR_LED "3i",
|
||||
D_SENSOR_LED "4i",
|
||||
D_SENSOR_MHZ_TX,
|
||||
D_SENSOR_MHZ_RX,
|
||||
D_SENSOR_PZEM_TX,
|
||||
D_SENSOR_PZEM_RX,
|
||||
D_SENSOR_SAIR_TX,
|
||||
D_SENSOR_SAIR_RX,
|
||||
D_SENSOR_SPI_CS,
|
||||
D_SENSOR_SPI_DC,
|
||||
D_SENSOR_BACKLIGHT
|
||||
};
|
||||
|
||||
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
||||
enum ProgramSelectablePins {
|
||||
GPIO_RXD = GPIO_SENSOR_END, // Serial interface
|
||||
@ -175,6 +107,30 @@ enum ProgramSelectablePins {
|
||||
GPIO_USER, // User configurable
|
||||
GPIO_MAX };
|
||||
|
||||
// Text in webpage Module Parameters and commands GPIOS and GPIO
|
||||
const char kSensorNames[] PROGMEM =
|
||||
D_SENSOR_NONE "|"
|
||||
D_SENSOR_DHT11 "|" D_SENSOR_AM2301 "|" D_SENSOR_SI7021 "|"
|
||||
D_SENSOR_DS18X20 "|"
|
||||
D_SENSOR_I2C_SCL "|" D_SENSOR_I2C_SDA "|"
|
||||
D_SENSOR_WS2812 "|"
|
||||
D_SENSOR_IRSEND "|"
|
||||
D_SENSOR_SWITCH "1|" D_SENSOR_SWITCH "2|" D_SENSOR_SWITCH "3|" D_SENSOR_SWITCH "4|"
|
||||
D_SENSOR_BUTTON "1|" D_SENSOR_BUTTON "2|" D_SENSOR_BUTTON "3|" D_SENSOR_BUTTON "4|"
|
||||
D_SENSOR_RELAY "1|" D_SENSOR_RELAY "2|" D_SENSOR_RELAY "3|" D_SENSOR_RELAY "4|" D_SENSOR_RELAY "5|" D_SENSOR_RELAY "6|" D_SENSOR_RELAY "7|" D_SENSOR_RELAY "8|"
|
||||
D_SENSOR_RELAY "1i|" D_SENSOR_RELAY "2i|" D_SENSOR_RELAY "3i|" D_SENSOR_RELAY "4i|" D_SENSOR_RELAY "5i|" D_SENSOR_RELAY "6i|" D_SENSOR_RELAY "7i|" D_SENSOR_RELAY "8i|"
|
||||
D_SENSOR_PWM "1|" D_SENSOR_PWM "2|" D_SENSOR_PWM "3|" D_SENSOR_PWM "4|" D_SENSOR_PWM "5|"
|
||||
D_SENSOR_COUNTER "1|" D_SENSOR_COUNTER "2|" D_SENSOR_COUNTER "3|" D_SENSOR_COUNTER "4|"
|
||||
D_SENSOR_PWM "1i|" D_SENSOR_PWM "2i|" D_SENSOR_PWM "3i|" D_SENSOR_PWM "4i|" D_SENSOR_PWM "5i|"
|
||||
D_SENSOR_IRRECV "|"
|
||||
D_SENSOR_LED "1|" D_SENSOR_LED "2|" D_SENSOR_LED "3|" D_SENSOR_LED "4|"
|
||||
D_SENSOR_LED "1i|" D_SENSOR_LED "2i|" D_SENSOR_LED "3i|" D_SENSOR_LED "4i|"
|
||||
D_SENSOR_MHZ_TX "|" D_SENSOR_MHZ_RX "|"
|
||||
D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"
|
||||
D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|"
|
||||
D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|"
|
||||
D_SENSOR_PMS5003;
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
// Supported hardware modules
|
||||
@ -219,6 +175,7 @@ enum SupportedModules {
|
||||
ARILUX_LC11,
|
||||
SONOFF_DUAL_R2,
|
||||
ARILUX_LC06,
|
||||
SONOFF_S31,
|
||||
MAXMODULE };
|
||||
|
||||
/********************************************************************************************/
|
||||
@ -243,6 +200,7 @@ const uint8_t kNiceList[MAXMODULE] PROGMEM = {
|
||||
SONOFF_DUAL,
|
||||
SONOFF_DUAL_R2,
|
||||
SONOFF_POW,
|
||||
SONOFF_S31,
|
||||
SONOFF_4CH,
|
||||
SONOFF_4CHPRO,
|
||||
SONOFF_SV,
|
||||
@ -499,7 +457,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||
GPIO_REL1, // GPIO15 Relay (0 = Off, 1 = On)
|
||||
0, 0
|
||||
},
|
||||
{ "WeMos D1 mini", // WeMos and NodeMCU hardware (ESP8266)
|
||||
{ "Generic", // Any ESP8266/ESP8285 device like WeMos and NodeMCU hardware (ESP8266)
|
||||
GPIO_USER, // GPIO00 D3 Wemos Button Shield
|
||||
GPIO_USER, // GPIO01 TX Serial RXD
|
||||
GPIO_USER, // GPIO02 D4 Wemos DHT Shield
|
||||
@ -815,6 +773,17 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||
GPIO_PWM1, // GPIO14 RGB LED Red
|
||||
GPIO_USER, // GPIO15 RGBW LED White
|
||||
0, 0
|
||||
},
|
||||
{ "Sonoff S31", // Sonoff S31 (ESP8266)
|
||||
GPIO_KEY1, // GPIO00 Button
|
||||
0, // GPIO01 Serial RXD 4800 baud 8E1 CSE7766 energy sensor
|
||||
0,
|
||||
0, // GPIO03 Serial TXD
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0, 0, // Flash connection
|
||||
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
|
||||
GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off)
|
||||
0, 0, 0, 0
|
||||
}
|
||||
};
|
||||
|
||||
@ -859,6 +828,44 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||
0, 0, 0
|
||||
}
|
||||
|
||||
{ "SMPW701E", // SM-PW701E WLAN Socket (#1190)
|
||||
0, 0, 0, 0,
|
||||
GPIO_LED1_INV, // GPIO04 Blue Led (0 = On, 1 = Off)
|
||||
0, // GPIO05 IR or RF receiver (optional)
|
||||
0, 0, 0, 0, 0, 0, // Flash connection
|
||||
GPIO_REL1, // GPIO12 Relay and Red Led (0 = Off, 1 = On)
|
||||
GPIO_KEY1, // GPIO13 Button
|
||||
0, 0, 0, 0
|
||||
}
|
||||
|
||||
{ "SWA1", // Smart Plugs (ESP8266)
|
||||
0,
|
||||
GPIO_USER, // GPIO01
|
||||
0,
|
||||
GPIO_USER, // GPIO03
|
||||
GPIO_LED1_INV, // GPIO04 Blue LED
|
||||
GPIO_REL1, // GPIO05 Red LED and relay
|
||||
0, 0, 0, 0, 0, 0, // Flash connection
|
||||
0,
|
||||
GPIO_KEY1, // GPIO13 Button (normally GPIO00)
|
||||
GPIO_USER, // GPIO14
|
||||
0, 0, 0
|
||||
}
|
||||
|
||||
{ "MagicHome v2.3", // Magic Home (aka Flux-light) (ESP8266) (#1353)
|
||||
0, 0,
|
||||
GPIO_LED1_INV, // GPIO02 Blue onboard LED
|
||||
0,
|
||||
GPIO_USER, // GPIO04 IR receiver (optional)
|
||||
GPIO_PWM2, // GPIO05 RGB LED Green
|
||||
0, 0, 0, 0, 0, 0, // Flash connection
|
||||
GPIO_PWM1, // GPIO12 RGB LED Red
|
||||
GPIO_PWM3, // GPIO13 RGB LED Blue
|
||||
0,
|
||||
GPIO_PWM4, // GPIO15 RGBW LED White
|
||||
0, 0
|
||||
},
|
||||
|
||||
*/
|
||||
|
||||
#endif // _SONOFF_TEMPLATE_H_
|
||||
@ -26,7 +26,7 @@ unsigned long syslog_host_refresh = 0;
|
||||
|
||||
Ticker tickerOSWatch;
|
||||
|
||||
#define OSWATCH_RESET_TIME 30
|
||||
#define OSWATCH_RESET_TIME 120
|
||||
|
||||
static unsigned long oswatch_last_loop_time;
|
||||
byte oswatch_blocked_loop = 0;
|
||||
@ -145,86 +145,56 @@ Decoding 14 results
|
||||
#endif // DEBUG_THEO
|
||||
|
||||
/*********************************************************************************************\
|
||||
* General
|
||||
* Miscellaneous
|
||||
\*********************************************************************************************/
|
||||
|
||||
char* _dtostrf(double number, unsigned char prec, char *s, bool i18n)
|
||||
#ifdef ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
// Functions not available in 2.3.0
|
||||
|
||||
// http://clc-wiki.net/wiki/C_standard_library:string.h:memchr
|
||||
void* memchr(const void* ptr, int value, size_t num)
|
||||
{
|
||||
bool negative = false;
|
||||
|
||||
if (isnan(number)) {
|
||||
strcpy_P(s, PSTR("nan"));
|
||||
return s;
|
||||
}
|
||||
if (isinf(number)) {
|
||||
strcpy_P(s, PSTR("inf"));
|
||||
return s;
|
||||
}
|
||||
char decimal = '.';
|
||||
if (i18n) {
|
||||
decimal = D_DECIMAL_SEPARATOR[0];
|
||||
}
|
||||
|
||||
char* out = s;
|
||||
|
||||
// Handle negative numbers
|
||||
if (number < 0.0) {
|
||||
negative = true;
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||
// I optimized out most of the divisions
|
||||
double rounding = 2.0;
|
||||
for (uint8_t i = 0; i < prec; ++i) {
|
||||
rounding *= 10.0;
|
||||
}
|
||||
rounding = 1.0 / rounding;
|
||||
number += rounding;
|
||||
|
||||
// Figure out how big our number really is
|
||||
double tenpow = 1.0;
|
||||
int digitcount = 1;
|
||||
while (number >= 10.0 * tenpow) {
|
||||
tenpow *= 10.0;
|
||||
digitcount++;
|
||||
}
|
||||
number /= tenpow;
|
||||
|
||||
// Handle negative sign
|
||||
if (negative) {
|
||||
*out++ = '-';
|
||||
}
|
||||
|
||||
// Print the digits, and if necessary, the decimal point
|
||||
digitcount += prec;
|
||||
int8_t digit = 0;
|
||||
while (digitcount-- > 0) {
|
||||
digit = (int8_t)number;
|
||||
if (digit > 9) {
|
||||
digit = 9; // insurance
|
||||
unsigned char *p = (unsigned char*)ptr;
|
||||
while (num--) {
|
||||
if (*p != (unsigned char)value) {
|
||||
p++;
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
*out++ = (char)('0' | digit);
|
||||
if ((digitcount == prec) && (prec > 0)) {
|
||||
*out++ = decimal;
|
||||
}
|
||||
number -= digit;
|
||||
number *= 10.0;
|
||||
}
|
||||
|
||||
// make sure the string is terminated
|
||||
*out = 0;
|
||||
return s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* dtostrfd(double number, unsigned char prec, char *s) // Always decimal dot
|
||||
// http://clc-wiki.net/wiki/C_standard_library:string.h:strspn
|
||||
// Get span until any character in string
|
||||
size_t strcspn(const char *str1, const char *str2)
|
||||
{
|
||||
return _dtostrf(number, prec, s, 0);
|
||||
size_t ret = 0;
|
||||
while (*str1) {
|
||||
if (strchr(str2, *str1)) { // Slow
|
||||
return ret;
|
||||
} else {
|
||||
str1++;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
|
||||
// Get span until single character in string
|
||||
size_t strchrspn(const char *str1, int character)
|
||||
{
|
||||
size_t ret = 0;
|
||||
char *start = (char*)str1;
|
||||
char *end = strchr(str1, character);
|
||||
if (end) ret = end - start;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* dtostrfi(double number, unsigned char prec, char *s) // Use localized decimal dot
|
||||
char* dtostrfd(double number, unsigned char prec, char *s)
|
||||
{
|
||||
return _dtostrf(number, prec, s, 1);
|
||||
return dtostrf(number, 1, prec, s);
|
||||
}
|
||||
|
||||
boolean ParseIp(uint32_t* addr, const char* str)
|
||||
@ -328,12 +298,127 @@ char* GetPowerDevice(char* dest, uint8_t idx, size_t size)
|
||||
return GetPowerDevice(dest, idx, size, 0);
|
||||
}
|
||||
|
||||
float ConvertTemp(float c)
|
||||
{
|
||||
float result = c;
|
||||
|
||||
if (!isnan(c) && Settings.flag.temperature_conversion) {
|
||||
result = c * 1.8 + 32; // Fahrenheit
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
char TempUnit()
|
||||
{
|
||||
return (Settings.flag.temperature_conversion) ? 'F' : 'C';
|
||||
}
|
||||
|
||||
double FastPrecisePow(double a, double b)
|
||||
{
|
||||
// https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
|
||||
// calculate approximation with fraction of the exponent
|
||||
int e = (int)b;
|
||||
union {
|
||||
double d;
|
||||
int x[2];
|
||||
} u = { a };
|
||||
u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447);
|
||||
u.x[0] = 0;
|
||||
// exponentiation by squaring with the exponent's integer part
|
||||
// double r = u.d makes everything much slower, not sure why
|
||||
double r = 1.0;
|
||||
while (e) {
|
||||
if (e & 1) {
|
||||
r *= a;
|
||||
}
|
||||
a *= a;
|
||||
e >>= 1;
|
||||
}
|
||||
return r * u.d;
|
||||
}
|
||||
|
||||
char* GetTextIndexed(char* destination, size_t destination_size, uint16_t index, const char* haystack)
|
||||
{
|
||||
// Returns empty string if not found
|
||||
// Returns text of found
|
||||
char* write = destination;
|
||||
const char* read = haystack;
|
||||
|
||||
index++;
|
||||
while (index--) {
|
||||
size_t size = destination_size -1;
|
||||
write = destination;
|
||||
char ch = '.';
|
||||
while ((ch != '\0') && (ch != '|')) {
|
||||
ch = pgm_read_byte(read++);
|
||||
if (size && (ch != '|')) {
|
||||
*write++ = ch;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
if (0 == ch) {
|
||||
if (index) {
|
||||
write = destination;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*write = '\0';
|
||||
return destination;
|
||||
}
|
||||
|
||||
int GetCommandCode(char* destination, size_t destination_size, const char* needle, const char* haystack)
|
||||
{
|
||||
// Returns -1 of not found
|
||||
// Returns index and command if found
|
||||
int result = -1;
|
||||
const char* read = haystack;
|
||||
char* write = destination;
|
||||
|
||||
while (true) {
|
||||
result++;
|
||||
size_t size = destination_size -1;
|
||||
write = destination;
|
||||
char ch = '.';
|
||||
while ((ch != '\0') && (ch != '|')) {
|
||||
ch = pgm_read_byte(read++);
|
||||
if (size && (ch != '|')) {
|
||||
*write++ = ch;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
*write = '\0';
|
||||
if (!strcasecmp(needle, destination)) {
|
||||
break;
|
||||
}
|
||||
if (0 == ch) {
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetSerialBaudrate(int baudrate)
|
||||
{
|
||||
if (Serial.baudRate() != baudrate) {
|
||||
if (seriallog_level) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_SET_BAUDRATE_TO " %d"), baudrate);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
}
|
||||
delay(100);
|
||||
Serial.flush();
|
||||
Serial.begin(baudrate, serial_config);
|
||||
delay(10);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Wifi
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define WIFI_CONFIG_SEC 180 // seconds before restart
|
||||
#define WIFI_MANAGER_SEC 180 // seconds before restart
|
||||
#define WIFI_CHECK_SEC 20 // seconds
|
||||
#define WIFI_RETRY_SEC 30 // seconds
|
||||
|
||||
@ -361,7 +446,7 @@ int WifiGetRssiAsQuality(int rssi)
|
||||
boolean WifiConfigCounter()
|
||||
{
|
||||
if (wifi_config_counter) {
|
||||
wifi_config_counter = WIFI_MANAGER_SEC;
|
||||
wifi_config_counter = WIFI_CONFIG_SEC;
|
||||
}
|
||||
return (wifi_config_counter);
|
||||
}
|
||||
@ -612,6 +697,12 @@ void WifiCheck(uint8_t param)
|
||||
WifiCheckIp();
|
||||
}
|
||||
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0) && !wifi_config_type) {
|
||||
#ifdef BE_MINIMAL
|
||||
if (1 == RtcSettings.ota_loader) {
|
||||
RtcSettings.ota_loader = 0;
|
||||
ota_state_flag = 3;
|
||||
}
|
||||
#endif // BE_MINIMAL
|
||||
#ifdef USE_DISCOVERY
|
||||
if (!mdns_begun) {
|
||||
mdns_begun = MDNS.begin(my_hostname);
|
||||
@ -902,22 +993,21 @@ uint32_t standard_time = 0;
|
||||
uint32_t ntp_time = 0;
|
||||
uint32_t midnight = 1451602800;
|
||||
uint8_t midnight_now = 0;
|
||||
uint8_t ntp_sync_minute = 0;
|
||||
|
||||
String GetBuildDateAndTime()
|
||||
{
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
char bdt[21];
|
||||
char *str;
|
||||
char *p;
|
||||
char *smonth;
|
||||
char mdate[] = __DATE__; // "Mar 7 2017"
|
||||
int month;
|
||||
int day;
|
||||
int year;
|
||||
char *smonth = mdate;
|
||||
int day = 0;
|
||||
int year = 0;
|
||||
|
||||
// sscanf(mdate, "%s %d %d", bdt, &day, &year); // Not implemented in 2.3.0 and probably too many code
|
||||
// sscanf(mdate, "%s %d %d", bdt, &day, &year); // Not implemented in 2.3.0 and probably too much code
|
||||
byte i = 0;
|
||||
for (str = strtok_r(mdate, " ", &p); str && i < 3; str = strtok_r(NULL, " ", &p)) {
|
||||
for (char *str = strtok_r(mdate, " ", &p); str && i < 3; str = strtok_r(NULL, " ", &p)) {
|
||||
switch (i++) {
|
||||
case 0: // Month
|
||||
smonth = str;
|
||||
@ -929,7 +1019,7 @@ String GetBuildDateAndTime()
|
||||
year = atoi(str);
|
||||
}
|
||||
}
|
||||
month = (strstr(kMonthNamesEnglish, smonth) -kMonthNamesEnglish) /3 +1;
|
||||
int month = (strstr(kMonthNamesEnglish, smonth) -kMonthNamesEnglish) /3 +1;
|
||||
snprintf_P(bdt, sizeof(bdt), PSTR("%d" D_YEAR_MONTH_SEPARATOR "%02d" D_MONTH_DAY_SEPARATOR "%02d" D_DATE_TIME_SEPARATOR "%s"), year, month, day, __TIME__);
|
||||
return String(bdt);
|
||||
}
|
||||
@ -958,6 +1048,22 @@ String GetUtcDateAndTime()
|
||||
return String(dt);
|
||||
}
|
||||
|
||||
String GetUptime()
|
||||
{
|
||||
char dt[16];
|
||||
|
||||
TIME_T ut;
|
||||
BreakTime(uptime, 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("%d" D_DATE_TIME_SEPARATOR "%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), ut.days, ut.hour, ut.minute, ut.second);
|
||||
return String(dt);
|
||||
}
|
||||
|
||||
void BreakTime(uint32_t time_input, TIME_T &tm)
|
||||
{
|
||||
// break the given time_input into time components
|
||||
@ -977,6 +1083,7 @@ void BreakTime(uint32_t time_input, TIME_T &tm)
|
||||
time /= 60; // now it is hours
|
||||
tm.hour = time % 24;
|
||||
time /= 24; // now it is days
|
||||
tm.days = time;
|
||||
tm.day_of_week = ((time + 4) % 7) + 1; // Sunday is day 1
|
||||
|
||||
year = 0;
|
||||
@ -1049,34 +1156,34 @@ uint32_t MakeTime(TIME_T &tm)
|
||||
|
||||
uint32_t RuleToTime(TimeChangeRule r, int yr)
|
||||
{
|
||||
TIME_T tm;
|
||||
uint32_t t;
|
||||
uint8_t m;
|
||||
uint8_t w; // temp copies of r.month and r.week
|
||||
TIME_T tm;
|
||||
uint32_t t;
|
||||
uint8_t m;
|
||||
uint8_t w; // temp copies of r.month and r.week
|
||||
|
||||
m = r.month;
|
||||
w = r.week;
|
||||
if (0 == w) { // Last week = 0
|
||||
if (++m > 12) { // for "Last", go to the next month
|
||||
m = 1;
|
||||
yr++;
|
||||
}
|
||||
w = 1; // and treat as first week of next month, subtract 7 days later
|
||||
m = r.month;
|
||||
w = r.week;
|
||||
if (0 == w) { // Last week = 0
|
||||
if (++m > 12) { // for "Last", go to the next month
|
||||
m = 1;
|
||||
yr++;
|
||||
}
|
||||
w = 1; // and treat as first week of next month, subtract 7 days later
|
||||
}
|
||||
|
||||
tm.hour = r.hour;
|
||||
tm.minute = 0;
|
||||
tm.second = 0;
|
||||
tm.day_of_month = 1;
|
||||
tm.month = m;
|
||||
tm.year = yr - 1970;
|
||||
t = MakeTime(tm); // First day of the month, or first day of next month for "Last" rules
|
||||
BreakTime(t, tm);
|
||||
t += (7 * (w - 1) + (r.dow - tm.day_of_week + 7) % 7) * SECS_PER_DAY;
|
||||
if (0 == r.week) {
|
||||
t -= 7 * SECS_PER_DAY; //back up a week if this is a "Last" rule
|
||||
}
|
||||
return t;
|
||||
tm.hour = r.hour;
|
||||
tm.minute = 0;
|
||||
tm.second = 0;
|
||||
tm.day_of_month = 1;
|
||||
tm.month = m;
|
||||
tm.year = yr - 1970;
|
||||
t = MakeTime(tm); // First day of the month, or first day of next month for "Last" rules
|
||||
BreakTime(t, tm);
|
||||
t += (7 * (w - 1) + (r.dow - tm.day_of_week + 7) % 7) * SECS_PER_DAY;
|
||||
if (0 == r.week) {
|
||||
t -= 7 * SECS_PER_DAY; // back up a week if this is a "Last" rule
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
String GetTime(int type)
|
||||
@ -1104,43 +1211,32 @@ uint32_t Midnight()
|
||||
boolean MidnightNow()
|
||||
{
|
||||
boolean mnflg = midnight_now;
|
||||
if (mnflg) {
|
||||
midnight_now = 0;
|
||||
}
|
||||
if (mnflg) midnight_now = 0;
|
||||
return mnflg;
|
||||
}
|
||||
|
||||
void RtcSecond()
|
||||
{
|
||||
byte ntpsync;
|
||||
uint32_t stdoffset;
|
||||
uint32_t dstoffset;
|
||||
TIME_T tmpTime;
|
||||
|
||||
ntpsync = 0;
|
||||
if (RtcTime.year < 2016) {
|
||||
if (WL_CONNECTED == WiFi.status()) {
|
||||
ntpsync = 1; // Initial NTP sync
|
||||
}
|
||||
} else {
|
||||
if ((1 == RtcTime.minute) && (1 == RtcTime.second)) {
|
||||
ntpsync = 1; // Hourly NTP sync at xx:01:01
|
||||
}
|
||||
}
|
||||
if (ntpsync) {
|
||||
if ((ntp_sync_minute > 59) && (3 == RtcTime.minute)) ntp_sync_minute = 1; // If sync prepare for a new cycle
|
||||
uint8_t offset = (uptime < 30) ? RtcTime.second : (((ESP.getChipId() & 0xF) * 3) + 3) ; // First try ASAP to sync. If fails try once every 60 seconds based on chip id
|
||||
if ((WL_CONNECTED == WiFi.status()) && (offset == RtcTime.second) && ((RtcTime.year < 2016) || (ntp_sync_minute == RtcTime.minute))) {
|
||||
ntp_time = sntp_get_current_timestamp();
|
||||
if (ntp_time) {
|
||||
utc_time = ntp_time;
|
||||
ntp_sync_minute = 60; // Sync so block further requests
|
||||
BreakTime(utc_time, tmpTime);
|
||||
RtcTime.year = tmpTime.year + 1970;
|
||||
daylight_saving_time = RuleToTime(DaylightSavingTime, RtcTime.year);
|
||||
standard_time = RuleToTime(StandardTime, RtcTime.year);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s"), GetTime(0).c_str());
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_DST_TIME ") %s"), GetTime(2).c_str());
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_STD_TIME ") %s"), GetTime(3).c_str());
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"),
|
||||
GetTime(0).c_str(), GetTime(2).c_str(), GetTime(3).c_str());
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
} else {
|
||||
ntp_sync_minute++; // Try again in next minute
|
||||
}
|
||||
}
|
||||
utc_time++;
|
||||
@ -1184,127 +1280,6 @@ void RtcInit()
|
||||
TickerRtc.attach(1, RtcSecond);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Miscellaneous
|
||||
\*********************************************************************************************/
|
||||
|
||||
float ConvertTemp(float c)
|
||||
{
|
||||
float result = c;
|
||||
|
||||
if (!isnan(c) && Settings.flag.temperature_conversion) {
|
||||
result = c * 1.8 + 32; // Fahrenheit
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
char TempUnit()
|
||||
{
|
||||
return (Settings.flag.temperature_conversion) ? 'F' : 'C';
|
||||
}
|
||||
|
||||
double FastPrecisePow(double a, double b)
|
||||
{
|
||||
// https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
|
||||
// calculate approximation with fraction of the exponent
|
||||
int e = (int)b;
|
||||
union {
|
||||
double d;
|
||||
int x[2];
|
||||
} u = { a };
|
||||
u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447);
|
||||
u.x[0] = 0;
|
||||
// exponentiation by squaring with the exponent's integer part
|
||||
// double r = u.d makes everything much slower, not sure why
|
||||
double r = 1.0;
|
||||
while (e) {
|
||||
if (e & 1) {
|
||||
r *= a;
|
||||
}
|
||||
a *= a;
|
||||
e >>= 1;
|
||||
}
|
||||
return r * u.d;
|
||||
}
|
||||
|
||||
char* GetTextIndexed(char* destination, size_t destination_size, uint16_t index, const char* haystack)
|
||||
{
|
||||
// Returns empty string if not found
|
||||
// Returns text of found
|
||||
char* write = destination;
|
||||
const char* read = haystack;
|
||||
|
||||
index++;
|
||||
while (index--) {
|
||||
size_t size = destination_size -1;
|
||||
write = destination;
|
||||
char ch = '.';
|
||||
while ((ch != '\0') && (ch != '|')) {
|
||||
ch = pgm_read_byte(read++);
|
||||
if (size && (ch != '|')) {
|
||||
*write++ = ch;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
if (0 == ch) {
|
||||
if (index) {
|
||||
write = destination;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*write = '\0';
|
||||
return destination;
|
||||
}
|
||||
|
||||
int GetCommandCode(char* destination, size_t destination_size, const char* needle, const char* haystack)
|
||||
{
|
||||
// Returns -1 of not found
|
||||
// Returns index and command if found
|
||||
int result = -1;
|
||||
const char* read = haystack;
|
||||
char* write = destination;
|
||||
size_t maxcopy = (strlen(needle) > destination_size) ? destination_size : strlen(needle);
|
||||
|
||||
while (true) {
|
||||
result++;
|
||||
size_t size = destination_size -1;
|
||||
write = destination;
|
||||
char ch = '.';
|
||||
while ((ch != '\0') && (ch != '|')) {
|
||||
ch = pgm_read_byte(read++);
|
||||
if (size && (ch != '|')) {
|
||||
*write++ = ch;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
*write = '\0';
|
||||
if (!strcasecmp(needle, destination)) {
|
||||
break;
|
||||
}
|
||||
if (0 == ch) {
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetSerialBaudrate(int baudrate)
|
||||
{
|
||||
if (Serial.baudRate() != baudrate) {
|
||||
if (seriallog_level) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_SET_BAUDRATE_TO " %d"), baudrate);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
}
|
||||
delay(100);
|
||||
Serial.flush();
|
||||
Serial.begin(baudrate);
|
||||
delay(10);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_ADC_VCC
|
||||
/*********************************************************************************************\
|
||||
* ADC support
|
||||
@ -1363,6 +1338,32 @@ boolean Xsns02(byte function)
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
void GetLog(byte idx, char** entry_pp, size_t* len_p)
|
||||
{
|
||||
char* entry_p = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if (idx) {
|
||||
char* it = web_log;
|
||||
do {
|
||||
byte cur_idx = *it;
|
||||
it++;
|
||||
size_t tmp = strchrspn(it, '\1');
|
||||
tmp++; // Skip terminating '\1'
|
||||
if (cur_idx == idx) { // Found the requested entry
|
||||
len = tmp;
|
||||
entry_p = it;
|
||||
break;
|
||||
}
|
||||
it += tmp;
|
||||
} while (it < web_log + WEB_LOG_SIZE && *it != '\0');
|
||||
}
|
||||
*entry_pp = entry_p;
|
||||
*len_p = len;
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void Syslog()
|
||||
{
|
||||
// Destroys log_data
|
||||
@ -1389,20 +1390,29 @@ void Syslog()
|
||||
|
||||
void AddLog(byte loglevel)
|
||||
{
|
||||
char mxtime[9]; // 13:45:21
|
||||
char mxtime[10]; // "13:45:21 "
|
||||
|
||||
snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second);
|
||||
snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d "), RtcTime.hour, RtcTime.minute, RtcTime.second);
|
||||
|
||||
if (loglevel <= seriallog_level) {
|
||||
Serial.printf("%s %s\n", mxtime, log_data);
|
||||
Serial.printf("%s%s\n", mxtime, log_data);
|
||||
}
|
||||
#ifdef USE_WEBSERVER
|
||||
if (Settings.webserver && (loglevel <= Settings.weblog_level)) {
|
||||
web_log[web_log_index] = String(mxtime) + " " + String(log_data);
|
||||
web_log_index++;
|
||||
if (web_log_index > MAX_LOG_LINES -1) {
|
||||
web_log_index = 0;
|
||||
// Delimited, zero-terminated buffer of log lines.
|
||||
// Each entry has this format: [index][log data]['\1']
|
||||
if (!web_log_index) web_log_index++; // Index 0 is not allowed as it is the end of char string
|
||||
while (web_log_index == web_log[0] || // If log already holds the next index, remove it
|
||||
strlen(web_log) + strlen(log_data) + 13 > WEB_LOG_SIZE) // 13 = web_log_index + mxtime + '\1' + '\0'
|
||||
{
|
||||
char* it = web_log;
|
||||
it++; // Skip web_log_index
|
||||
it += strchrspn(it, '\1'); // Skip log line
|
||||
it++; // Skip delimiting "\1"
|
||||
memmove(web_log, it, WEB_LOG_SIZE -(it-web_log)); // Move buffer forward to remove oldest log line
|
||||
}
|
||||
snprintf_P(web_log, sizeof(web_log), PSTR("%s%c%s%s\1"), web_log, web_log_index++, mxtime, log_data);
|
||||
if (!web_log_index) web_log_index++; // Index 0 is not allowed as it is the end of char string
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
if ((WL_CONNECTED == WiFi.status()) && (loglevel <= syslog_level)) {
|
||||
@ -1426,6 +1436,15 @@ void AddLog_P(byte loglevel, const char *formatP, const char *formatP2)
|
||||
AddLog(loglevel);
|
||||
}
|
||||
|
||||
void AddLogSerial(byte loglevel)
|
||||
{
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SERIAL D_RECEIVED));
|
||||
for (byte i = 0; i < serial_in_byte_counter; i++) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, serial_in_buffer[i]);
|
||||
}
|
||||
AddLog(loglevel);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
@ -29,11 +29,14 @@
|
||||
\*********************************************************************************************/
|
||||
|
||||
// -- Localization --------------------------------
|
||||
//#define MY_LANGUAGE en-GB // English in Great Britain. Enabled by Default
|
||||
//#define MY_LANGUAGE nl-NL // Dutch in the Netherlands
|
||||
//#define MY_LANGUAGE de-DE // German in Germany
|
||||
//#define MY_LANGUAGE pl-PL // Polish in Poland
|
||||
//#define MY_LANGUAGE en-GB // English in Great Britain. Enabled by Default
|
||||
//#define MY_LANGUAGE es-AR // Spanish in Argentina
|
||||
//#define MY_LANGUAGE fr-FR // French in France
|
||||
//#define MY_LANGUAGE it-IT // Italian in Italy
|
||||
//#define MY_LANGUAGE nl-NL // Dutch in the Netherlands
|
||||
//#define MY_LANGUAGE pl-PL // Polish in Poland
|
||||
//#define MY_LANGUAGE zh-CN // Chinese (Simplified) in China
|
||||
|
||||
// -- Project -------------------------------------
|
||||
#define PROJECT "sonoff" // PROJECT is used as the default topic delimiter and OTA file name
|
||||
@ -116,6 +119,11 @@
|
||||
#define DOMOTICZ_OUT_TOPIC "domoticz/out" // Domoticz Output Topic
|
||||
#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional)
|
||||
|
||||
// -- MQTT - Home Assistant Discovery -------------
|
||||
#define USE_HOME_ASSISTANT // Enable Home Assistant Discovery Support (+1k4 code)
|
||||
#define HOME_ASSISTANT_DISCOVERY_PREFIX "homeassistant" // Home Assistant discovery prefix
|
||||
#define HOME_ASSISTANT_DISCOVERY_ENABLE 0 // [SetOption19] Home Assistant Discovery (0 = Disable, 1 = Enable)
|
||||
|
||||
// -- HTTP ----------------------------------------
|
||||
#define USE_WEBSERVER // Enable web server and wifi manager (+66k code, +8k mem) - Disable by //
|
||||
#define WEB_SERVER 2 // [WebServer] Web server (0 = Off, 1 = Start as User, 2 = Start as Admin)
|
||||
@ -161,11 +169,10 @@
|
||||
#define PRESSURE_RESOLUTION 1 // [PressRes] Maximum number of decimals (0 - 3) showing sensor Pressure
|
||||
#define ENERGY_RESOLUTION 3 // [EnergyRes] Maximum number of decimals (0 - 5) showing energy usage in kWh
|
||||
|
||||
// -- Sensor code selection -----------------------
|
||||
// -- Internal Analog input -----------------------
|
||||
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
|
||||
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
|
||||
// -- One wire sensors ----------------------------
|
||||
// WARNING: Select none for default one DS18B20 sensor or enable one of the following two options for multiple sensors
|
||||
//#define USE_DS18x20 // Optional for more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code)
|
||||
//#define USE_DS18x20_LEGACY // Optional for more than one DS18x20 sensors with dynamic scan using library OneWire (+1k5 code)
|
||||
@ -186,14 +193,15 @@
|
||||
// #define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code)
|
||||
#endif // USE_I2C
|
||||
|
||||
//#define USE_SPI // SPI using library TasmotaTFT
|
||||
|
||||
// -- Carbon dioxide (CO2) sensors ----------------
|
||||
// -- Serial sensors ------------------------------
|
||||
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
|
||||
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
|
||||
#define CO2_LOW 800 // Below this CO2 value show green light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1)
|
||||
#define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1)
|
||||
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
|
||||
// -- Low level interface devices -----------------
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||
// #define USE_IR_HVAC // Support for HVAC system using IR (+2k code)
|
||||
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
|
||||
@ -202,7 +210,7 @@
|
||||
#define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB, 2 - RGBW, 3 - GRBW)
|
||||
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow
|
||||
|
||||
#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code)
|
||||
#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code, 252 iram (non 2.3.0))
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Compile a minimal version if upgrade memory gets tight ONLY TO BE USED FOR UPGRADE STEP 1!
|
||||
|
||||
@ -37,7 +37,7 @@ const char HTTP_HEAD[] PROGMEM =
|
||||
|
||||
"<script>"
|
||||
"var cn,x,lt;"
|
||||
"cn=120;"
|
||||
"cn=180;"
|
||||
"x=null;" // Allow for abortion
|
||||
"function u(){"
|
||||
"if(cn>=0){"
|
||||
@ -60,7 +60,7 @@ const char HTTP_HEAD[] PROGMEM =
|
||||
"x=new XMLHttpRequest();"
|
||||
"x.onreadystatechange=function(){"
|
||||
"if(x.readyState==4&&x.status==200){"
|
||||
"var s=x.responseText.replace(/{s}/g,\"<tr><th>\").replace(/{m}/g,\"</th><td>\").replace(/{e}/g,\"</td></tr>\").replace(/{t}/g,\"%'><div style='text-align:center;font-weight:\");"
|
||||
"var s=x.responseText.replace(/{t}/g,\"<table style='width:100%'>\").replace(/{s}/g,\"<tr><th>\").replace(/{m}/g,\"</th><td>\").replace(/{e}/g,\"</td></tr>\").replace(/{c}/g,\"%'><div style='text-align:center;font-weight:\");"
|
||||
"document.getElementById('l1').innerHTML=s;"
|
||||
"}"
|
||||
"};"
|
||||
@ -73,7 +73,9 @@ const char HTTP_HEAD[] PROGMEM =
|
||||
"}"
|
||||
"function lc(p){"
|
||||
"la('?t='+p);"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
const char HTTP_HEAD_STYLE[] PROGMEM =
|
||||
"</script>"
|
||||
|
||||
"<style>"
|
||||
@ -83,7 +85,7 @@ const char HTTP_HEAD[] PROGMEM =
|
||||
"textarea{resize:none;width:98%;height:318px;padding:5px;overflow:auto;}"
|
||||
"body{text-align:center;font-family:verdana;}"
|
||||
"td{padding:0px;}"
|
||||
"button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;-webkit-transition-duration:0.4s;transition-duration:0.4s;}"
|
||||
"button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;-webkit-transition-duration:0.4s;transition-duration:0.4s;cursor:pointer;}"
|
||||
"button:hover{background-color:#006cba;}"
|
||||
"a{text-decoration:none;}"
|
||||
".p{float:left;text-align:left;}"
|
||||
@ -96,10 +98,14 @@ const char HTTP_HEAD[] PROGMEM =
|
||||
#ifdef BE_MINIMAL
|
||||
"<div style='text-align:center;color:red;'><h3>" D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "</h3></div>"
|
||||
#endif
|
||||
#ifdef LANGUAGE_MODULE_NAME
|
||||
"<div style='text-align:center;'><h3>" D_MODULE " {ha</h3><h2>{h}</h2></div>";
|
||||
#else
|
||||
"<div style='text-align:center;'><h3>{ha " D_MODULE "</h3><h2>{h}</h2></div>";
|
||||
#endif
|
||||
const char HTTP_SCRIPT_CONSOL[] PROGMEM =
|
||||
"var sn=0;" // Scroll position
|
||||
"var id=99;" // Get most of weblog initially
|
||||
"var id=0;" // Get most of weblog initially
|
||||
"function l(p){" // Console log and command service
|
||||
"var c,o,t;"
|
||||
"clearTimeout(lt);"
|
||||
@ -190,6 +196,12 @@ const char HTTP_BTN_MENU4[] PROGMEM =
|
||||
"<br/><form action='rs' method='get'><button>" D_RESTORE_CONFIGURATION "</button></form>";
|
||||
const char HTTP_BTN_MAIN[] PROGMEM =
|
||||
"<br/><br/><form action='.' method='get'><button>" D_MAIN_MENU "</button></form>";
|
||||
const char HTTP_FORM_LOGIN[] PROGMEM =
|
||||
"<form method='post' action='/'>"
|
||||
"<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/>"
|
||||
"<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 =
|
||||
@ -204,9 +216,9 @@ const char HTTP_FORM_WIFI[] PROGMEM =
|
||||
"<fieldset><legend><b> " D_WIFI_PARAMETERS " </b></legend><form method='get' action='sv'>"
|
||||
"<input id='w' name='w' value='1' hidden><input id='r' name='r' value='1' hidden>"
|
||||
"<br/><b>" D_AP1_SSID "</b> (" STA_SSID1 ")<br/><input id='s1' name='s1' placeholder='" STA_SSID1 "' value='{s1'><br/>"
|
||||
"<br/><b>" D_AP1_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" STA_PASS1 "' value='{p1'><br/>"
|
||||
"<br/><b>" D_AP1_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" D_AP1_PASSWORD "' value='********'><br/>"
|
||||
"<br/><b>" D_AP2_SSID "</b> (" STA_SSID2 ")<br/><input id='s2' name='s2' placeholder='" STA_SSID2 "' value='{s2'><br/>"
|
||||
"<br/><b>" D_AP2_PASSWORD "</b><br/><input id='p2' name='p2' type='password' placeholder='" STA_PASS2 "' value='{p2'><br/>"
|
||||
"<br/><b>" D_AP2_PASSWORD "</b><br/><input id='p2' name='p2' type='password' placeholder='" D_AP2_PASSWORD "' value='********'><br/>"
|
||||
"<br/><b>" D_HOSTNAME "</b> (" WIFI_HOSTNAME ")<br/><input id='h' name='h' placeholder='" WIFI_HOSTNAME" ' value='{h1'><br/>";
|
||||
const char HTTP_FORM_MQTT[] PROGMEM =
|
||||
"<fieldset><legend><b> " D_MQTT_PARAMETERS " </b></legend><form method='get' action='sv'>"
|
||||
@ -236,7 +248,7 @@ const char HTTP_FORM_LOG3[] PROGMEM =
|
||||
const char HTTP_FORM_OTHER[] PROGMEM =
|
||||
"<fieldset><legend><b> " D_OTHER_PARAMETERS " </b></legend><form method='get' action='sv'>"
|
||||
"<input id='w' name='w' value='5' hidden><input id='r' name='r' value='1' hidden>"
|
||||
"<br/><b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" WEB_PASSWORD "' value='{p1'><br/>"
|
||||
"<br/><b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" D_WEB_ADMIN_PASSWORD "' value='********'><br/>"
|
||||
"<br/><input style='width:10%;' id='b1' name='b1' type='checkbox'{r1><b>" D_MQTT_ENABLE "</b><br/>";
|
||||
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/>";
|
||||
@ -244,8 +256,8 @@ const char HTTP_FORM_OTHER[] PROGMEM =
|
||||
const char HTTP_FORM_OTHER3a[] PROGMEM =
|
||||
"<br/><fieldset><legend><b> " D_EMULATION " </b></legend>";
|
||||
const char HTTP_FORM_OTHER3b[] PROGMEM =
|
||||
"<br/><input style='width:10%;' id='b2' name='b2' type='radio' value='{1'{2><b>{3</b>{4";
|
||||
#endif // USE_EMULATION
|
||||
"<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
|
||||
#endif // USE_EMULATION
|
||||
const char HTTP_FORM_END[] PROGMEM =
|
||||
"<br/><button type='submit'>" D_SAVE "</button></form></fieldset>";
|
||||
const char HTTP_FORM_RST[] PROGMEM =
|
||||
@ -267,18 +279,18 @@ const char HTTP_FORM_RST_UPG[] PROGMEM =
|
||||
"</div>"
|
||||
"<div id='f2' name='f2' style='display:none;text-align:center;'><b>" D_UPLOAD_STARTED " ...</b></div>";
|
||||
const char HTTP_FORM_CMND[] PROGMEM =
|
||||
"<br/><textarea readonly id='t1' name='t1' cols='" STR(MESSZ) "' wrap='off'></textarea><br/><br/>"
|
||||
"<br/><textarea readonly id='t1' name='t1' cols='340' wrap='off'></textarea><br/><br/>"
|
||||
"<form method='get' onsubmit='return l(1);'>"
|
||||
"<input id='c1' name='c1' placeholder='" D_ENTER_COMMAND "' autofocus><br/>"
|
||||
// "<br/><button type='submit'>Send command</button>"
|
||||
"</form>";
|
||||
const char HTTP_TABLE100[] PROGMEM =
|
||||
"<table width='100%'>";
|
||||
"<table style='width:100%'>";
|
||||
const char HTTP_COUNTER[] PROGMEM =
|
||||
"<br/><div id='t' name='t' style='text-align:center;'></div>";
|
||||
const char HTTP_END[] PROGMEM =
|
||||
"<br/>"
|
||||
"<div style='text-align:right;font-size:11px;'><hr/><a href='" D_WEBLINK "' target='_blank' style='color:#aaa;'>" D_PROGRAMNAME " " VERSION_STRING " " D_BY " " D_AUTHOR "</a></div>"
|
||||
"<div style='text-align:right;font-size:11px;'><hr/><a href='" D_WEBLINK "' target='_blank' style='color:#aaa;'>" D_PROGRAMNAME " {mv " D_BY " " D_AUTHOR "</a></div>"
|
||||
"</div>"
|
||||
"</body>"
|
||||
"</html>";
|
||||
@ -302,6 +314,14 @@ uint8_t upload_error = 0;
|
||||
uint8_t upload_file_type;
|
||||
uint8_t upload_progress_dot_count;
|
||||
|
||||
// Helper function to avoid code duplication (saves 4k Flash)
|
||||
static void WebGetArg(const char* arg, char* out, size_t max)
|
||||
{
|
||||
String s = WebServer->arg(arg);
|
||||
strncpy(out, s.c_str(), max);
|
||||
out[max-1] = '\0'; // Ensure terminating NUL
|
||||
}
|
||||
|
||||
void StartWebserver(int type, IPAddress ipweb)
|
||||
{
|
||||
if (!webserver_state) {
|
||||
@ -402,18 +422,24 @@ void PollDnsWebserver()
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void SetHeader()
|
||||
{
|
||||
WebServer->sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate"));
|
||||
WebServer->sendHeader(F("Pragma"), F("no-cache"));
|
||||
WebServer->sendHeader(F("Expires"), F("-1"));
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
WebServer->sendHeader(F("Access-Control-Allow-Origin"), F("*"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShowPage(String &page)
|
||||
void ShowPage(String &page, bool auth)
|
||||
{
|
||||
if((HTTP_ADMIN == webserver_state) && (Settings.web_password[0] != 0) && !WebServer->authenticate(WEB_USERNAME, Settings.web_password)) {
|
||||
if (auth && (Settings.web_password[0] != 0) && !WebServer->authenticate(WEB_USERNAME, Settings.web_password)) {
|
||||
return WebServer->requestAuthentication();
|
||||
}
|
||||
|
||||
page.replace(F("{ha"), my_module.name);
|
||||
page.replace(F("{h}"), Settings.friendlyname[0]);
|
||||
if (HTTP_MANAGER == webserver_state) {
|
||||
@ -423,13 +449,29 @@ void ShowPage(String &page)
|
||||
}
|
||||
}
|
||||
page += FPSTR(HTTP_END);
|
||||
page.replace(F("{mv"), my_version);
|
||||
SetHeader();
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_HTML), page);
|
||||
}
|
||||
|
||||
void ShowPage(String &page)
|
||||
{
|
||||
ShowPage(page, true);
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void HandleWifiLogin()
|
||||
{
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR( D_CONFIGURE_WIFI ));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_LOGIN);
|
||||
ShowPage(page, false); // false means show page no matter if the client has or has not credentials
|
||||
}
|
||||
|
||||
void HandleRoot()
|
||||
{
|
||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MAIN_MENU));
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_MAIN_MENU);
|
||||
|
||||
if (CaptivePortal()) { // If captive portal redirect instead of displaying the page.
|
||||
@ -437,31 +479,47 @@ void HandleRoot()
|
||||
}
|
||||
|
||||
if (HTTP_MANAGER == webserver_state) {
|
||||
HandleWifiConfiguration();
|
||||
if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1"))) {
|
||||
HandleWifiLogin();
|
||||
} else {
|
||||
/*
|
||||
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();
|
||||
} else {
|
||||
// wrong user and pass
|
||||
HandleWifiLogin();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char stemp[10];
|
||||
char line[160];
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_MAIN_MENU));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page.replace(F("<body>"), F("<body onload='la()'>"));
|
||||
|
||||
page += F("<div id='l1' name='l1'></div>");
|
||||
if (devices_present) {
|
||||
if (light_type) {
|
||||
if ((LST_COLDWARM == (light_type &7)) || (LST_RGBWC == (light_type &7))) {
|
||||
snprintf_P(line, sizeof(line), HTTP_MSG_SLIDER1, LightGetColorTemp());
|
||||
page += line;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_MSG_SLIDER1, LightGetColorTemp());
|
||||
page += mqtt_data;
|
||||
}
|
||||
snprintf_P(line, sizeof(line), HTTP_MSG_SLIDER2, Settings.light_dimmer);
|
||||
page += line;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_MSG_SLIDER2, Settings.light_dimmer);
|
||||
page += mqtt_data;
|
||||
}
|
||||
page += FPSTR(HTTP_TABLE100);
|
||||
page += F("<tr>");
|
||||
for (byte idx = 1; idx <= devices_present; idx++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), idx);
|
||||
snprintf_P(line, sizeof(line), PSTR("<td width='%d%'><button onclick='la(\"?o=%d\");'>%s%s</button></td>"),
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>%s%s</button></td>"),
|
||||
100 / devices_present, idx, (devices_present < 5) ? D_BUTTON_TOGGLE : "", (devices_present > 1) ? stemp : "");
|
||||
page += line;
|
||||
page += mqtt_data;
|
||||
}
|
||||
page += F("</tr></table>");
|
||||
}
|
||||
@ -475,8 +533,8 @@ void HandleRoot()
|
||||
}
|
||||
for (byte j = 0; j < 4; j++) {
|
||||
idx++;
|
||||
snprintf_P(line, sizeof(line), PSTR("<td width='25%'><button onclick='la(\"?k=%d\");'>%d</button></td>"), idx, idx);
|
||||
page += line;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<td style='width:25%'><button onclick='la(\"?k=%d\");'>%d</button></td>"), idx, idx);
|
||||
page += mqtt_data;
|
||||
}
|
||||
}
|
||||
page += F("</tr></table>");
|
||||
@ -493,54 +551,49 @@ void HandleRoot()
|
||||
void HandleAjaxStatusRefresh()
|
||||
{
|
||||
char svalue[80];
|
||||
char tmp[100];
|
||||
|
||||
if (strlen(WebServer->arg("o").c_str())) {
|
||||
ExecuteCommandPower(atoi(WebServer->arg("o").c_str()), 2);
|
||||
WebGetArg("o", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) {
|
||||
ExecuteCommandPower(atoi(tmp), POWER_TOGGLE);
|
||||
}
|
||||
if (strlen(WebServer->arg("d").c_str())) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_DIMMER " %s"), WebServer->arg("d").c_str());
|
||||
WebGetArg("d", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_DIMMER " %s"), tmp);
|
||||
ExecuteCommand(svalue);
|
||||
}
|
||||
if (strlen(WebServer->arg("t").c_str())) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_COLORTEMPERATURE " %s"), WebServer->arg("t").c_str());
|
||||
WebGetArg("t", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_COLORTEMPERATURE " %s"), tmp);
|
||||
ExecuteCommand(svalue);
|
||||
}
|
||||
if (strlen(WebServer->arg("k").c_str())) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RFKEY "%s"), WebServer->arg("k").c_str());
|
||||
WebGetArg("k", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RFKEY "%s"), tmp);
|
||||
ExecuteCommand(svalue);
|
||||
}
|
||||
|
||||
String page = "";
|
||||
mqtt_data[0] = '\0';
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{t}"));
|
||||
XsnsCall(FUNC_WEB_APPEND);
|
||||
if (strlen(mqtt_data)) {
|
||||
page += FPSTR(HTTP_TABLE100);
|
||||
page += mqtt_data;
|
||||
page += F("</table>");
|
||||
if (D_DECIMAL_SEPARATOR[0] != '.') {
|
||||
for (uint16_t i = 0; i < strlen(mqtt_data); i++) {
|
||||
if ('.' == mqtt_data[i]) {
|
||||
mqtt_data[i] = D_DECIMAL_SEPARATOR[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
char line[80];
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s</table>"), mqtt_data);
|
||||
if (devices_present) {
|
||||
page += FPSTR(HTTP_TABLE100);
|
||||
page += F("<tr>");
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{t}<tr>"), mqtt_data);
|
||||
uint8_t fsize = (devices_present < 5) ? 70 - (devices_present * 8) : 32;
|
||||
for (byte idx = 1; idx <= devices_present; idx++) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(power, idx -1));
|
||||
// snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:%s;font-size:%dpx'>%s</div></td>"),
|
||||
snprintf_P(line, sizeof(line), PSTR("<td width='%d{t}%s;font-size:%dpx'>%s</div></td>"), // {t} = %'><div style='text-align:center;font-weight:
|
||||
100 / devices_present, (bitRead(power, idx -1)) ? "bold" : "normal", fsize, (devices_present < 5) ? GetStateText(bitRead(power, idx -1)) : svalue);
|
||||
page += line;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s<td style='width:%d{c}%s;font-size:%dpx'>%s</div></td>"), // {c} = %'><div style='text-align:center;font-weight:
|
||||
mqtt_data, 100 / devices_present, (bitRead(power, idx -1)) ? "bold" : "normal", fsize, (devices_present < 5) ? GetStateText(bitRead(power, idx -1)) : svalue);
|
||||
}
|
||||
page += F("</tr></table>");
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s</tr></table>"), mqtt_data);
|
||||
}
|
||||
/*
|
||||
* Will interrupt user action when selected
|
||||
if (light_type) {
|
||||
snprintf_P(line, sizeof(line), PSTR("<input type='range' min='1' max='100' value='%d' onchange='lb(value)'>"),
|
||||
Settings.light_dimmer);
|
||||
page += line;
|
||||
}
|
||||
*/
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_HTML), page);
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_HTML), mqtt_data);
|
||||
}
|
||||
|
||||
boolean HttpUser()
|
||||
@ -561,6 +614,7 @@ void HandleConfiguration()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_BTN_MENU2);
|
||||
if (Settings.flag.mqtt_enabled) {
|
||||
page += FPSTR(HTTP_BTN_MENU3);
|
||||
@ -632,56 +686,57 @@ void HandleModuleConfiguration()
|
||||
return;
|
||||
}
|
||||
char stemp[20];
|
||||
char line[160];
|
||||
uint8_t midx;
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MODULE);
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE));
|
||||
page += FPSTR(HTTP_FORM_MODULE);
|
||||
snprintf_P(stemp, sizeof(stemp), kModules[MODULE].name);
|
||||
page.replace(F("{mt"), stemp);
|
||||
page += FPSTR(HTTP_SCRIPT_MODULE1);
|
||||
for (byte i = 0; i < MAXMODULE; i++) {
|
||||
midx = pgm_read_byte(kNiceList + i);
|
||||
snprintf_P(stemp, sizeof(stemp), kModules[midx].name);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx +1, stemp);
|
||||
page += mqtt_data;
|
||||
}
|
||||
page += FPSTR(HTTP_SCRIPT_MODULE3);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("sk(%d,99);o0=\""), Settings.module); // g99
|
||||
page += mqtt_data;
|
||||
|
||||
mytmplt cmodule;
|
||||
memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule));
|
||||
|
||||
String func = FPSTR(HTTP_SCRIPT_MODULE1);
|
||||
for (byte i = 0; i < MAXMODULE; i++) {
|
||||
midx = pgm_read_byte(kNiceList + i);
|
||||
snprintf_P(stemp, sizeof(stemp), kModules[midx].name);
|
||||
snprintf_P(line, sizeof(line), HTTP_SCRIPT_MODULE2, midx, midx +1, stemp);
|
||||
func += line;
|
||||
}
|
||||
func += FPSTR(HTTP_SCRIPT_MODULE3);
|
||||
snprintf_P(line, sizeof(line), PSTR("sk(%d,99);o0=\""), Settings.module); // g99
|
||||
func += line;
|
||||
for (byte j = 0; j < GPIO_SENSOR_END; j++) {
|
||||
if (!GetUsedInModule(j, cmodule.gp.io)) {
|
||||
snprintf_P(stemp, sizeof(stemp), kSensors[j]);
|
||||
snprintf_P(line, sizeof(line), HTTP_SCRIPT_MODULE2, j, j, stemp);
|
||||
func += line;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, j, j, GetTextIndexed(stemp, sizeof(stemp), j, kSensorNames));
|
||||
page += mqtt_data;
|
||||
}
|
||||
}
|
||||
func += FPSTR(HTTP_SCRIPT_MODULE3);
|
||||
page += FPSTR(HTTP_SCRIPT_MODULE3);
|
||||
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("sk(%d,%d);"), my_module.gp.io[i], i); // g0 - g16
|
||||
page += mqtt_data;
|
||||
}
|
||||
}
|
||||
page += F("}");
|
||||
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page.replace(F("<body>"), F("<body onload='sl()'>"));
|
||||
page += FPSTR(HTTP_FORM_MODULE);
|
||||
snprintf_P(stemp, sizeof(stemp), kModules[MODULE].name);
|
||||
page.replace(F("{mt"), stemp);
|
||||
page += F("<br/><table>");
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
||||
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
||||
snprintf_P(line, sizeof(line), PSTR("<tr><td width='190'>%s <b>" D_GPIO "%d</b> %s</td><td width='126'><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:126px'><select id='g%d' name='g%d'></select></td></tr>"),
|
||||
(WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
||||
page += line;
|
||||
snprintf_P(line, sizeof(line), PSTR("sk(%d,%d);"), my_module.gp.io[i], i); // g0 - g16
|
||||
func += line;
|
||||
page += mqtt_data;
|
||||
}
|
||||
}
|
||||
page += F("</table>");
|
||||
|
||||
func += F("}</script>");
|
||||
page.replace(F("</script>"), func);
|
||||
page.replace(F("<body>"), F("<body onload='sl()'>"));
|
||||
|
||||
page += FPSTR(HTTP_FORM_END);
|
||||
page += FPSTR(HTTP_BTN_CONF);
|
||||
ShowPage(page);
|
||||
@ -707,6 +762,7 @@ void HandleWifi(boolean scan)
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_WIFI));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
|
||||
if (scan) {
|
||||
#ifdef USE_EMULATION
|
||||
@ -786,16 +842,15 @@ void HandleWifi(boolean scan)
|
||||
page += FPSTR(HTTP_FORM_WIFI);
|
||||
page.replace(F("{h1"), Settings.hostname);
|
||||
page.replace(F("{s1"), Settings.sta_ssid[0]);
|
||||
page.replace(F("{p1"), Settings.sta_pwd[0]);
|
||||
page.replace(F("{s2"), Settings.sta_ssid[1]);
|
||||
page.replace(F("{p2"), Settings.sta_pwd[1]);
|
||||
page += FPSTR(HTTP_FORM_END);
|
||||
if (HTTP_MANAGER == webserver_state) {
|
||||
page += FPSTR(HTTP_BTN_RSTRT);
|
||||
} else {
|
||||
page += FPSTR(HTTP_BTN_CONF);
|
||||
}
|
||||
ShowPage(page);
|
||||
// ShowPage(page);
|
||||
ShowPage(page, !(HTTP_MANAGER == webserver_state));
|
||||
}
|
||||
|
||||
void HandleMqttConfiguration()
|
||||
@ -807,6 +862,7 @@ void HandleMqttConfiguration()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MQTT));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_MQTT);
|
||||
char str[sizeof(Settings.mqtt_client)];
|
||||
GetMqttClient(str, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client));
|
||||
@ -832,6 +888,7 @@ void HandleLoggingConfiguration()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_LOGGING));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_LOG1);
|
||||
for (byte idx = 0; idx < 3; idx++) {
|
||||
page += FPSTR(HTTP_FORM_LOG2);
|
||||
@ -881,13 +938,17 @@ void HandleOtherConfiguration()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_OTHER));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_OTHER);
|
||||
page.replace(F("{p1"), Settings.web_password);
|
||||
page.replace(F("{r1"), (Settings.flag.mqtt_enabled) ? F(" checked") : F(""));
|
||||
page += FPSTR(HTTP_FORM_OTHER2);
|
||||
page.replace(F("{1"), F("1"));
|
||||
page.replace(F("{2"), FRIENDLY_NAME);
|
||||
page.replace(F("{3"), Settings.friendlyname[0]);
|
||||
uint8_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present;
|
||||
for (byte i = 0; i < maxfn; i++) {
|
||||
page += FPSTR(HTTP_FORM_OTHER2);
|
||||
page.replace(F("{1"), String(i +1));
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR(FRIENDLY_NAME"%d"), i +1);
|
||||
page.replace(F("{2"), (i) ? stemp : FRIENDLY_NAME);
|
||||
page.replace(F("{3"), Settings.friendlyname[i]);
|
||||
}
|
||||
#ifdef USE_EMULATION
|
||||
page += FPSTR(HTTP_FORM_OTHER3a);
|
||||
for (byte i = 0; i < EMUL_MAX; i++) {
|
||||
@ -898,14 +959,6 @@ void HandleOtherConfiguration()
|
||||
page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" " D_SINGLE_DEVICE) : F(" " D_MULTI_DEVICE));
|
||||
}
|
||||
page += F("<br/>");
|
||||
uint8_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present;
|
||||
for (byte i = 1; i < maxfn; i++) {
|
||||
page += FPSTR(HTTP_FORM_OTHER2);
|
||||
page.replace(F("{1"), String(i +1));
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR(FRIENDLY_NAME"%d"), i +1);
|
||||
page.replace(F("{2"), stemp);
|
||||
page.replace(F("{3"), Settings.friendlyname[i]);
|
||||
}
|
||||
page += F("<br/></fieldset>");
|
||||
#endif // USE_EMULATION
|
||||
page += FPSTR(HTTP_FORM_END);
|
||||
@ -926,8 +979,7 @@ void HandleBackupConfiguration()
|
||||
WebServer->setContentLength(sizeof(buffer));
|
||||
|
||||
char attachment[100];
|
||||
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_" VERSION_STRING ".dmp"),
|
||||
Settings.friendlyname[0]);
|
||||
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), Settings.friendlyname[0], my_version);
|
||||
WebServer->sendHeader(F("Content-Disposition"), attachment);
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
|
||||
memcpy(buffer, &Settings, sizeof(buffer));
|
||||
@ -955,57 +1007,81 @@ void HandleSaveSettings()
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_SAVE_CONFIGURATION);
|
||||
|
||||
if (strlen(WebServer->arg("w").c_str())) {
|
||||
what = atoi(WebServer->arg("w").c_str());
|
||||
char tmp[100];
|
||||
WebGetArg("w", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) {
|
||||
what = atoi(tmp);
|
||||
}
|
||||
switch (what) {
|
||||
case 1:
|
||||
strlcpy(Settings.hostname, (!strlen(WebServer->arg("h").c_str())) ? WIFI_HOSTNAME : WebServer->arg("h").c_str(), sizeof(Settings.hostname));
|
||||
WebGetArg("h", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.hostname, (!strlen(tmp)) ? WIFI_HOSTNAME : tmp, sizeof(Settings.hostname));
|
||||
if (strstr(Settings.hostname,"%")) {
|
||||
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname));
|
||||
}
|
||||
strlcpy(Settings.sta_ssid[0], (!strlen(WebServer->arg("s1").c_str())) ? STA_SSID1 : WebServer->arg("s1").c_str(), sizeof(Settings.sta_ssid[0]));
|
||||
strlcpy(Settings.sta_pwd[0], (!strlen(WebServer->arg("p1").c_str())) ? STA_PASS1 : WebServer->arg("p1").c_str(), sizeof(Settings.sta_pwd[0]));
|
||||
strlcpy(Settings.sta_ssid[1], (!strlen(WebServer->arg("s2").c_str())) ? STA_SSID2 : WebServer->arg("s2").c_str(), sizeof(Settings.sta_ssid[1]));
|
||||
strlcpy(Settings.sta_pwd[1], (!strlen(WebServer->arg("p2").c_str())) ? STA_PASS2 : WebServer->arg("p2").c_str(), sizeof(Settings.sta_pwd[1]));
|
||||
WebGetArg("s1", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.sta_ssid[0], (!strlen(tmp)) ? STA_SSID1 : tmp, sizeof(Settings.sta_ssid[0]));
|
||||
WebGetArg("s2", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.sta_ssid[1], (!strlen(tmp)) ? STA_SSID2 : tmp, sizeof(Settings.sta_ssid[1]));
|
||||
// WebGetArg("s1", tmp, sizeof(tmp));
|
||||
// strlcpy(Settings.sta_ssid[0], (!strlen(tmp)) ? "" : tmp, sizeof(Settings.sta_ssid[0]));
|
||||
// WebGetArg("s2", tmp, sizeof(tmp));
|
||||
// strlcpy(Settings.sta_ssid[1], (!strlen(tmp)) ? "" : tmp, sizeof(Settings.sta_ssid[1]));
|
||||
WebGetArg("p1", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.sta_pwd[0], (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? Settings.sta_pwd[0] : tmp, sizeof(Settings.sta_pwd[0]));
|
||||
WebGetArg("p2", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.sta_pwd[1], (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? 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_PASSWORD "1 %s, " D_CMND_SSID "2 %s, " D_CMND_PASSWORD "2 %s"),
|
||||
Settings.hostname, Settings.sta_ssid[0], Settings.sta_pwd[0], Settings.sta_ssid[1], Settings.sta_pwd[1]);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
result += F("<br/>" D_TRYING_TO_CONNECT "<br/>");
|
||||
break;
|
||||
case 2:
|
||||
strlcpy(stemp, (!strlen(WebServer->arg("mt").c_str())) ? MQTT_TOPIC : WebServer->arg("mt").c_str(), sizeof(stemp));
|
||||
WebGetArg("mt", tmp, sizeof(tmp));
|
||||
strlcpy(stemp, (!strlen(tmp)) ? MQTT_TOPIC : tmp, sizeof(stemp));
|
||||
MakeValidMqtt(0, stemp);
|
||||
strlcpy(stemp2, (!strlen(WebServer->arg("mf").c_str())) ? MQTT_FULLTOPIC : WebServer->arg("mf").c_str(), sizeof(stemp2));
|
||||
WebGetArg("mf", tmp, sizeof(tmp));
|
||||
strlcpy(stemp2, (!strlen(tmp)) ? MQTT_FULLTOPIC : tmp, sizeof(stemp2));
|
||||
MakeValidMqtt(1,stemp2);
|
||||
if ((strcmp(stemp, Settings.mqtt_topic)) || (strcmp(stemp2, Settings.mqtt_fulltopic))) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), (Settings.flag.mqtt_offline) ? S_OFFLINE : "");
|
||||
MqttPublishPrefixTopic_P(2, S_LWT, true); // Offline or remove previous retained topic
|
||||
MqttPublishPrefixTopic_P(TELE, S_LWT, true); // Offline or remove previous retained topic
|
||||
}
|
||||
strlcpy(Settings.mqtt_topic, stemp, sizeof(Settings.mqtt_topic));
|
||||
strlcpy(Settings.mqtt_fulltopic, stemp2, sizeof(Settings.mqtt_fulltopic));
|
||||
strlcpy(Settings.mqtt_host, (!strlen(WebServer->arg("mh").c_str())) ? MQTT_HOST : (!strcmp(WebServer->arg("mh").c_str(),"0")) ? "" : WebServer->arg("mh").c_str(), sizeof(Settings.mqtt_host));
|
||||
Settings.mqtt_port = (!strlen(WebServer->arg("ml").c_str())) ? MQTT_PORT : atoi(WebServer->arg("ml").c_str());
|
||||
strlcpy(Settings.mqtt_client, (!strlen(WebServer->arg("mc").c_str())) ? MQTT_CLIENT_ID : WebServer->arg("mc").c_str(), sizeof(Settings.mqtt_client));
|
||||
strlcpy(Settings.mqtt_user, (!strlen(WebServer->arg("mu").c_str())) ? MQTT_USER : (!strcmp(WebServer->arg("mu").c_str(),"0")) ? "" : WebServer->arg("mu").c_str(), sizeof(Settings.mqtt_user));
|
||||
strlcpy(Settings.mqtt_pwd, (!strlen(WebServer->arg("mp").c_str())) ? MQTT_PASS : (!strcmp(WebServer->arg("mp").c_str(),"0")) ? "" : WebServer->arg("mp").c_str(), sizeof(Settings.mqtt_pwd));
|
||||
WebGetArg("mh", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.mqtt_host, (!strlen(tmp)) ? MQTT_HOST : (!strcmp(tmp,"0")) ? "" : tmp, sizeof(Settings.mqtt_host));
|
||||
WebGetArg("ml", tmp, sizeof(tmp));
|
||||
Settings.mqtt_port = (!strlen(tmp)) ? MQTT_PORT : atoi(tmp);
|
||||
WebGetArg("mc", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.mqtt_client, (!strlen(tmp)) ? MQTT_CLIENT_ID : tmp, sizeof(Settings.mqtt_client));
|
||||
WebGetArg("mu", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.mqtt_user, (!strlen(tmp)) ? MQTT_USER : (!strcmp(tmp,"0")) ? "" : tmp, sizeof(Settings.mqtt_user));
|
||||
WebGetArg("mp", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.mqtt_pwd, (!strlen(tmp)) ? MQTT_PASS : (!strcmp(tmp,"0")) ? "" : 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_MQTTPASSWORD " %s, " D_CMND_TOPIC " %s, " D_CMND_FULLTOPIC " %s"),
|
||||
Settings.mqtt_host, Settings.mqtt_port, Settings.mqtt_client, Settings.mqtt_user, Settings.mqtt_pwd, Settings.mqtt_topic, Settings.mqtt_fulltopic);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
break;
|
||||
case 3:
|
||||
Settings.seriallog_level = (!strlen(WebServer->arg("ls").c_str())) ? SERIAL_LOG_LEVEL : atoi(WebServer->arg("ls").c_str());
|
||||
Settings.weblog_level = (!strlen(WebServer->arg("lw").c_str())) ? WEB_LOG_LEVEL : atoi(WebServer->arg("lw").c_str());
|
||||
Settings.syslog_level = (!strlen(WebServer->arg("ll").c_str())) ? SYS_LOG_LEVEL : atoi(WebServer->arg("ll").c_str());
|
||||
WebGetArg("ls", tmp, sizeof(tmp));
|
||||
Settings.seriallog_level = (!strlen(tmp)) ? SERIAL_LOG_LEVEL : atoi(tmp);
|
||||
WebGetArg("lw", tmp, sizeof(tmp));
|
||||
Settings.weblog_level = (!strlen(tmp)) ? WEB_LOG_LEVEL : atoi(tmp);
|
||||
WebGetArg("ll", tmp, sizeof(tmp));
|
||||
Settings.syslog_level = (!strlen(tmp)) ? SYS_LOG_LEVEL : atoi(tmp);
|
||||
syslog_level = Settings.syslog_level;
|
||||
syslog_timer = 0;
|
||||
strlcpy(Settings.syslog_host, (!strlen(WebServer->arg("lh").c_str())) ? SYS_LOG_HOST : WebServer->arg("lh").c_str(), sizeof(Settings.syslog_host));
|
||||
Settings.syslog_port = (!strlen(WebServer->arg("lp").c_str())) ? SYS_LOG_PORT : atoi(WebServer->arg("lp").c_str());
|
||||
Settings.tele_period = (!strlen(WebServer->arg("lt").c_str())) ? TELE_PERIOD : atoi(WebServer->arg("lt").c_str());
|
||||
WebGetArg("lh", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.syslog_host, (!strlen(tmp)) ? SYS_LOG_HOST : tmp, sizeof(Settings.syslog_host));
|
||||
WebGetArg("lp", tmp, sizeof(tmp));
|
||||
Settings.syslog_port = (!strlen(tmp)) ? SYS_LOG_PORT : atoi(tmp);
|
||||
WebGetArg("lt", tmp, sizeof(tmp));
|
||||
Settings.tele_period = (!strlen(tmp)) ? TELE_PERIOD : atoi(tmp);
|
||||
if ((Settings.tele_period > 0) && (Settings.tele_period < 10)) {
|
||||
Settings.tele_period = 10; // Do not allow periods < 10 seconds
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D_CMND_WEBLOG " %d, " D_CMND_SYSLOG " %d, " D_CMND_LOGHOST " %s, " D_CMND_LOGPORT " %d, " D_CMND_TELEPERIOD " %d"),
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D_CMND_WEBLOG " %d, " D_CMND_SYSLOG " %d, " D_CMND_LOGHOST " %s, " D_CMND_LOGPORT " %d, " D_CMND_TELEPERIOD " %d"),
|
||||
Settings.seriallog_level, Settings.weblog_level, Settings.syslog_level, Settings.syslog_host, Settings.syslog_port, Settings.tele_period);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
break;
|
||||
@ -1015,21 +1091,28 @@ snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D
|
||||
break;
|
||||
#endif // USE_DOMOTICZ
|
||||
case 5:
|
||||
strlcpy(Settings.web_password, (!strlen(WebServer->arg("p1").c_str())) ? WEB_PASSWORD : (!strcmp(WebServer->arg("p1").c_str(),"0")) ? "" : WebServer->arg("p1").c_str(), sizeof(Settings.web_password));
|
||||
WebGetArg("p1", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.web_password, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? Settings.web_password : tmp, sizeof(Settings.web_password));
|
||||
Settings.flag.mqtt_enabled = WebServer->hasArg("b1");
|
||||
#ifdef USE_EMULATION
|
||||
Settings.flag2.emulation = (!strlen(WebServer->arg("b2").c_str())) ? 0 : atoi(WebServer->arg("b2").c_str());
|
||||
WebGetArg("b2", tmp, sizeof(tmp));
|
||||
Settings.flag2.emulation = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
#endif // USE_EMULATION
|
||||
strlcpy(Settings.friendlyname[0], (!strlen(WebServer->arg("a1").c_str())) ? FRIENDLY_NAME : WebServer->arg("a1").c_str(), sizeof(Settings.friendlyname[0]));
|
||||
strlcpy(Settings.friendlyname[1], (!strlen(WebServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : WebServer->arg("a2").c_str(), sizeof(Settings.friendlyname[1]));
|
||||
strlcpy(Settings.friendlyname[2], (!strlen(WebServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : WebServer->arg("a3").c_str(), sizeof(Settings.friendlyname[2]));
|
||||
strlcpy(Settings.friendlyname[3], (!strlen(WebServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : WebServer->arg("a4").c_str(), sizeof(Settings.friendlyname[3]));
|
||||
WebGetArg("a1", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.friendlyname[0], (!strlen(tmp)) ? FRIENDLY_NAME : tmp, sizeof(Settings.friendlyname[0]));
|
||||
WebGetArg("a2", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.friendlyname[1], (!strlen(tmp)) ? FRIENDLY_NAME"2" : tmp, sizeof(Settings.friendlyname[1]));
|
||||
WebGetArg("a3", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.friendlyname[2], (!strlen(tmp)) ? FRIENDLY_NAME"3" : tmp, sizeof(Settings.friendlyname[2]));
|
||||
WebGetArg("a4", tmp, sizeof(tmp));
|
||||
strlcpy(Settings.friendlyname[3], (!strlen(tmp)) ? FRIENDLY_NAME"4" : tmp, sizeof(Settings.friendlyname[3]));
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME " %s, %s, %s, %s"),
|
||||
GetStateText(Settings.flag.mqtt_enabled), Settings.flag2.emulation, Settings.friendlyname[0], Settings.friendlyname[1], Settings.friendlyname[2], Settings.friendlyname[3]);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
break;
|
||||
case 6:
|
||||
byte new_module = (!strlen(WebServer->arg("g99").c_str())) ? MODULE : atoi(WebServer->arg("g99").c_str());
|
||||
WebGetArg("g99", tmp, sizeof(tmp));
|
||||
byte new_module = (!strlen(tmp)) ? MODULE : atoi(tmp);
|
||||
Settings.last_module = Settings.module;
|
||||
Settings.module = new_module;
|
||||
mytmplt cmodule;
|
||||
@ -1041,7 +1124,8 @@ snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D
|
||||
} else {
|
||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
|
||||
Settings.my_gp.io[i] = (!strlen(WebServer->arg(stemp).c_str())) ? 0 : atoi(WebServer->arg(stemp).c_str());
|
||||
WebGetArg(stemp, tmp, sizeof(tmp));
|
||||
Settings.my_gp.io[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(Settings.my_gp.io[i]);
|
||||
}
|
||||
}
|
||||
@ -1052,10 +1136,12 @@ snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D
|
||||
break;
|
||||
}
|
||||
|
||||
restart = (!strlen(WebServer->arg("r").c_str())) ? 1 : atoi(WebServer->arg("r").c_str());
|
||||
WebGetArg("r", tmp, sizeof(tmp));
|
||||
restart = (!strlen(tmp)) ? 1 : atoi(tmp);
|
||||
if (restart) {
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_SAVE_CONFIGURATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += F("<div style='text-align:center;'><b>" D_CONFIGURATION_SAVED "</b><br/>");
|
||||
page += result;
|
||||
page += F("</div>");
|
||||
@ -1079,12 +1165,13 @@ void HandleResetConfiguration()
|
||||
return;
|
||||
}
|
||||
|
||||
char svalue[16];
|
||||
char svalue[33];
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_RESET_CONFIGURATION);
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_RESET_CONFIGURATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += F("<div style='text-align:center;'>" D_CONFIGURATION_RESET "</div>");
|
||||
page += FPSTR(HTTP_MSG_RSTRT);
|
||||
page += FPSTR(HTTP_BTN_MAIN);
|
||||
@ -1103,6 +1190,7 @@ void HandleRestoreConfiguration()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_RESTORE_CONFIGURATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_RST);
|
||||
page += FPSTR(HTTP_FORM_RST_UPG);
|
||||
page.replace(F("{r1"), F(D_RESTORE));
|
||||
@ -1122,6 +1210,7 @@ void HandleUpgradeFirmware()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_FIRMWARE_UPGRADE));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_UPG);
|
||||
page.replace(F("{o1"), Settings.ota_url);
|
||||
page += FPSTR(HTTP_FORM_RST_UPG);
|
||||
@ -1143,13 +1232,16 @@ void HandleUpgradeFirmwareStart()
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_UPGRADE_STARTED));
|
||||
WifiConfigCounter();
|
||||
|
||||
if (strlen(WebServer->arg("o").c_str())) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_OTAURL " %s"), WebServer->arg("o").c_str());
|
||||
char tmp[100];
|
||||
WebGetArg("o", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_OTAURL " %s"), tmp);
|
||||
ExecuteCommand(svalue);
|
||||
}
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_INFORMATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += F("<div style='text-align:center;'><b>" D_UPGRADE_STARTED " ...</b></div>");
|
||||
page += FPSTR(HTTP_MSG_RSTRT);
|
||||
page += FPSTR(HTTP_BTN_MAIN);
|
||||
@ -1174,6 +1266,7 @@ void HandleUploadDone()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_INFORMATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += F("<div style='text-align:center;'><b>" D_UPLOAD " <font color='");
|
||||
if (upload_error) {
|
||||
page += F("red'>" D_FAILED "</font></b><br/><br/>");
|
||||
@ -1235,6 +1328,9 @@ void HandleUploadLoop()
|
||||
#ifdef USE_EMULATION
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
#ifdef USE_ARILUX_RF
|
||||
AriluxRfDisable(); // Prevent restart exception on Arilux Interrupt routine
|
||||
#endif // USE_ARILUX_RF
|
||||
if (Settings.flag.mqtt_enabled) {
|
||||
MqttClient.disconnect();
|
||||
}
|
||||
@ -1333,7 +1429,11 @@ void HandleHttpCommand()
|
||||
|
||||
uint8_t valid = 1;
|
||||
if (Settings.web_password[0] != 0) {
|
||||
if (!(!strcmp(WebServer->arg("user").c_str(),WEB_USERNAME) && !strcmp(WebServer->arg("password").c_str(),Settings.web_password))) {
|
||||
char tmp1[100];
|
||||
WebGetArg("user", tmp1, sizeof(tmp1));
|
||||
char tmp2[100];
|
||||
WebGetArg("password", tmp2, sizeof(tmp2));
|
||||
if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, Settings.web_password))) {
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
@ -1341,9 +1441,8 @@ void HandleHttpCommand()
|
||||
String message = F("{\"" D_RSLT_WARNING "\":\"");
|
||||
if (valid) {
|
||||
byte curridx = web_log_index;
|
||||
if (strlen(WebServer->arg("cmnd").c_str())) {
|
||||
// snprintf_P(svalue, sizeof(svalue), WebServer->arg("cmnd").c_str()); // Processes FullTopic %p
|
||||
strlcpy(svalue, WebServer->arg("cmnd").c_str(), sizeof(svalue)); // Fixed 5.8.0b
|
||||
WebGetArg("cmnd", svalue, sizeof(svalue));
|
||||
if (strlen(svalue)) {
|
||||
// byte syslog_now = syslog_level;
|
||||
// syslog_level = 0; // Disable UDP syslog to not trigger hardware WDT - Seems to work fine since 5.7.1d (global logging)
|
||||
ExecuteCommand(svalue);
|
||||
@ -1354,19 +1453,23 @@ void HandleHttpCommand()
|
||||
byte counter = curridx;
|
||||
message = F("{");
|
||||
do {
|
||||
if (web_log[counter].length()) {
|
||||
char* tmp;
|
||||
size_t len;
|
||||
GetLog(counter, &tmp, &len);
|
||||
if (len) {
|
||||
// [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}]
|
||||
if (web_log[counter].indexOf("{") > 0) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
|
||||
char* JSON = (char*)memchr(tmp, '{', len);
|
||||
if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
|
||||
if (message.length() > 1) {
|
||||
message += F(",");
|
||||
}
|
||||
message += web_log[counter].substring(web_log[counter].indexOf("{")+1,web_log[counter].length()-1);
|
||||
size_t JSONlen = len - (JSON - tmp);
|
||||
strlcpy(mqtt_data, JSON +1, JSONlen -2);
|
||||
message += mqtt_data;
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
if (counter > MAX_LOG_LINES -1) {
|
||||
counter = 0;
|
||||
}
|
||||
if (!counter) counter++; // Skip 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
message += F("}");
|
||||
} else {
|
||||
@ -1375,6 +1478,7 @@ void HandleHttpCommand()
|
||||
} else {
|
||||
message += F(D_NEED_USER_AND_PASSWORD "\"}");
|
||||
}
|
||||
SetHeader();
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_JSON), message);
|
||||
}
|
||||
|
||||
@ -1388,6 +1492,7 @@ void HandleConsole()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONSOLE));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_CONSOL));
|
||||
page.replace(F("<body>"), F("<body onload='l()'>"));
|
||||
page += FPSTR(HTTP_FORM_CMND);
|
||||
@ -1402,11 +1507,10 @@ void HandleAjaxConsoleRefresh()
|
||||
}
|
||||
char svalue[INPUT_BUFFER_SIZE]; // big to serve Backlog
|
||||
byte cflg = 1;
|
||||
byte counter = 99;
|
||||
byte counter = 0; // Initial start, should never be 0 again
|
||||
|
||||
if (strlen(WebServer->arg("c1").c_str())) {
|
||||
// snprintf_P(svalue, sizeof(svalue), WebServer->arg("c1").c_str()); // Processes FullTopic %p
|
||||
strlcpy(svalue, WebServer->arg("c1").c_str(), sizeof(svalue)); // Fixed 5.8.0b
|
||||
WebGetArg("c1", svalue, sizeof(svalue));
|
||||
if (strlen(svalue)) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
// byte syslog_now = syslog_level;
|
||||
@ -1415,43 +1519,46 @@ void HandleAjaxConsoleRefresh()
|
||||
// syslog_level = syslog_now;
|
||||
}
|
||||
|
||||
if (strlen(WebServer->arg("c2").c_str())) {
|
||||
counter = atoi(WebServer->arg("c2").c_str());
|
||||
WebGetArg("c2", svalue, sizeof(svalue));
|
||||
if (strlen(svalue)) {
|
||||
counter = atoi(svalue);
|
||||
}
|
||||
|
||||
String message = F("<r><i>");
|
||||
message += String(web_log_index);
|
||||
message += F("</i><j>");
|
||||
message += String(reset_web_log_flag);
|
||||
byte last_reset_web_log_flag = reset_web_log_flag;
|
||||
String message = F("}9"); // Cannot load mqtt_data here as <> will be encoded by replacements below
|
||||
if (!reset_web_log_flag) {
|
||||
counter = 99;
|
||||
counter = 0;
|
||||
reset_web_log_flag = 1;
|
||||
}
|
||||
message += F("</j><l>");
|
||||
if (counter != web_log_index) {
|
||||
if (99 == counter) {
|
||||
if (!counter) {
|
||||
counter = web_log_index;
|
||||
cflg = 0;
|
||||
}
|
||||
do {
|
||||
if (web_log[counter].length()) {
|
||||
char* tmp;
|
||||
size_t len;
|
||||
GetLog(counter, &tmp, &len);
|
||||
if (len) {
|
||||
if (cflg) {
|
||||
message += F("\n");
|
||||
} else {
|
||||
cflg = 1;
|
||||
}
|
||||
String nextline = web_log[counter];
|
||||
nextline.replace(F("<"), F("%3C")); // XML encoding to fix blank console log in concert with javascript decodeURIComponent
|
||||
nextline.replace(F(">"), F("%3E"));
|
||||
nextline.replace(F("&"), F("%26"));
|
||||
message += nextline;
|
||||
strlcpy(mqtt_data, tmp, len);
|
||||
message += mqtt_data;
|
||||
}
|
||||
counter++;
|
||||
if (counter > MAX_LOG_LINES -1) {
|
||||
counter = 0;
|
||||
}
|
||||
if (!counter) counter++; // Skip 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
// XML encoding to fix blank console log in concert with javascript decodeURIComponent
|
||||
message.replace(F("%"), F("%25")); // Needs to be done first as otherwise the % in %26 will also be converted
|
||||
message.replace(F("&"), F("%26"));
|
||||
message.replace(F("<"), F("%3C"));
|
||||
message.replace(F(">"), F("%3E"));
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<r><i>%d</i><j>%d</j><l>"), web_log_index, last_reset_web_log_flag);
|
||||
message.replace(F("}9"), mqtt_data); // Save to load here
|
||||
message += F("</l></r>");
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_XML), message);
|
||||
}
|
||||
@ -1469,6 +1576,7 @@ void HandleInformation()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_INFORMATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
// page += F("<fieldset><legend><b> Information </b></legend>");
|
||||
|
||||
page += F("<style>td{padding:0px 5px;}</style>");
|
||||
@ -1478,11 +1586,11 @@ void HandleInformation()
|
||||
// }1 = </td></tr><tr><th>
|
||||
// }2 = </th><td>
|
||||
String func = FPSTR(HTTP_SCRIPT_INFO_BEGIN);
|
||||
func += F("<table width='100%'><tr><th>");
|
||||
func += F(D_PROGRAM_VERSION "}2" VERSION_STRING);
|
||||
func += F("<table style='width:100%'><tr><th>");
|
||||
func += F(D_PROGRAM_VERSION "}2"); func += my_version;
|
||||
func += F("}1" D_BUILD_DATE_AND_TIME "}2"); func += GetBuildDateAndTime();
|
||||
func += F("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_ESP8266_RELEASE "/"); func += String(ESP.getSdkVersion());
|
||||
func += F("}1" D_UPTIME "}2"); func += String(uptime); func += F(" Hours");
|
||||
func += F("}1" D_UPTIME "}2"); func += GetUptime();
|
||||
snprintf_P(stopic, sizeof(stopic), PSTR(" at %X"), GetSettingsAddress());
|
||||
func += F("}1" D_FLASH_WRITE_COUNT "}2"); func += String(Settings.save_flag); func += stopic;
|
||||
func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount);
|
||||
@ -1517,7 +1625,7 @@ void HandleInformation()
|
||||
func += F("}1" D_MQTT_USER "}2"); func += Settings.mqtt_user;
|
||||
func += F("}1" D_MQTT_TOPIC "}2"); func += Settings.mqtt_topic;
|
||||
func += F("}1" D_MQTT_GROUP_TOPIC "}2"); func += Settings.mqtt_grptopic;
|
||||
GetTopic_P(stopic, 0, Settings.mqtt_topic, "");
|
||||
GetTopic_P(stopic, CMND, Settings.mqtt_topic, "");
|
||||
func += F("}1" D_MQTT_FULL_TOPIC "}2"); func += stopic;
|
||||
|
||||
} else {
|
||||
@ -1580,6 +1688,7 @@ void HandleRestart()
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_RESTART));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_MSG_RSTRT);
|
||||
if (HTTP_MANAGER == webserver_state) {
|
||||
webserver_state = HTTP_ADMIN;
|
||||
@ -1609,18 +1718,13 @@ void HandleNotFound()
|
||||
} else
|
||||
#endif // USE_EMULATION
|
||||
{
|
||||
String message = F(D_FILE_NOT_FOUND "\n\nURI: ");
|
||||
message += WebServer->uri();
|
||||
message += F("\nMethod: ");
|
||||
message += (WebServer->method() == HTTP_GET) ? F("GET") : F("POST");
|
||||
message += F("\nArguments: ");
|
||||
message += WebServer->args();
|
||||
message += F("\n");
|
||||
for ( uint8_t i = 0; i < WebServer->args(); i++ ) {
|
||||
message += " " + WebServer->argName(i) + ": " + WebServer->arg(i) + "\n";
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_FILE_NOT_FOUND "\n\nURI: %s\nMethod: %s\nArguments: %d\n"),
|
||||
WebServer->uri().c_str(), (WebServer->method() == HTTP_GET) ? "GET" : "POST", WebServer->args());
|
||||
for (uint8_t i = 0; i < WebServer->args(); i++) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s %s: %s\n"), mqtt_data, WebServer->argName(i).c_str(), WebServer->arg(i).c_str());
|
||||
}
|
||||
SetHeader();
|
||||
WebServer->send(404, FPSTR(HDR_CTYPE_PLAIN), message);
|
||||
WebServer->send(404, FPSTR(HDR_CTYPE_PLAIN), mqtt_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1631,8 +1735,8 @@ boolean CaptivePortal()
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
|
||||
|
||||
WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true);
|
||||
WebServer->send(302, FPSTR(HDR_CTYPE_PLAIN), ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
|
||||
WebServer->client().stop(); // Stop is needed because we sent no content length
|
||||
WebServer->send(302, FPSTR(HDR_CTYPE_PLAIN), ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
|
||||
WebServer->client().stop(); // Stop is needed because we sent no content length
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -99,6 +99,7 @@ uint8_t light_signal_color[5];
|
||||
|
||||
uint8_t light_wheel = 0;
|
||||
uint8_t light_subtype = 0;
|
||||
uint8_t light_device = 0;
|
||||
uint8_t light_power = 0;
|
||||
uint8_t light_update = 1;
|
||||
uint8_t light_wakeup_active = 0;
|
||||
@ -107,7 +108,7 @@ uint16_t light_wakeup_counter = 0;
|
||||
|
||||
uint8_t light_fixed_color_index = 1;
|
||||
|
||||
unsigned long strip_timer_counter = 0; // Bars and Gradient
|
||||
unsigned long strip_timer_counter = 0; // Bars and Gradient
|
||||
|
||||
#ifdef USE_ARILUX_RF
|
||||
/*********************************************************************************************\
|
||||
@ -132,9 +133,12 @@ unsigned int arilux_rf_repeat_count = 0;
|
||||
|
||||
uint8_t arilux_rf_toggle = 0;
|
||||
|
||||
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
#ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves RF misses
|
||||
//void AriluxRfInterrupt() ICACHE_RAM_ATTR; // As iram is tight and it works this way too
|
||||
void AriluxRfInterrupt() ICACHE_RAM_ATTR; // As iram is tight and it works this way too
|
||||
#endif // USE_WS2812_DMA
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
|
||||
void AriluxRfInterrupt()
|
||||
{
|
||||
@ -188,7 +192,7 @@ void AriluxRfHandler()
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (hostcode == stored_hostcode) {
|
||||
char command[16];
|
||||
char command[33];
|
||||
char value = '-';
|
||||
command[0] = '\0';
|
||||
uint8_t keycode = arilux_rf_received_value & 0xFF;
|
||||
@ -248,8 +252,8 @@ void AriluxRfInit()
|
||||
void AriluxRfDisable()
|
||||
{
|
||||
if ((pin[GPIO_ARIRFRCV] < 99) && (pin[GPIO_LED2] < 99)) {
|
||||
digitalWrite(pin[GPIO_LED2], bitRead(led_inverted, 1)); // Turn off RF
|
||||
detachInterrupt(pin[GPIO_ARIRFRCV]);
|
||||
digitalWrite(pin[GPIO_LED2], bitRead(led_inverted, 1)); // Turn off RF
|
||||
}
|
||||
}
|
||||
#endif // USE_ARILUX_RF
|
||||
@ -337,6 +341,7 @@ void LightInit()
|
||||
{
|
||||
uint8_t max_scheme = LS_MAX -1;
|
||||
|
||||
light_device = devices_present;
|
||||
light_subtype = light_type &7;
|
||||
|
||||
if (light_type < LT_PWM6) { // PWM
|
||||
@ -364,13 +369,9 @@ void LightInit()
|
||||
}
|
||||
}
|
||||
if (pin[GPIO_ARIRFRCV] < 99) {
|
||||
#ifdef USE_ARILUX_RF
|
||||
AriluxRfInit();
|
||||
#else
|
||||
if (pin[GPIO_LED2] < 99) {
|
||||
digitalWrite(pin[GPIO_LED2], bitRead(led_inverted, 1)); // Turn off RF
|
||||
}
|
||||
#endif // USE_ARILUX_RF
|
||||
}
|
||||
}
|
||||
#ifdef USE_WS2812 // ************************************************************************
|
||||
@ -526,33 +527,58 @@ char* LightGetColor(uint8_t type, char* scolor)
|
||||
void LightPowerOn()
|
||||
{
|
||||
if (Settings.light_dimmer && !(light_power)) {
|
||||
ExecuteCommandPower(devices_present, 1);
|
||||
ExecuteCommandPower(light_device, POWER_ON);
|
||||
}
|
||||
}
|
||||
|
||||
void LightState(uint8_t append)
|
||||
{
|
||||
char scolor[25];
|
||||
char scommand[33];
|
||||
|
||||
if (append) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
||||
}
|
||||
GetPowerDevice(scommand, light_device, sizeof(scommand));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"),
|
||||
mqtt_data, scommand, GetStateText(light_power), Settings.light_dimmer);
|
||||
if (light_subtype > LST_SINGLE) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor));
|
||||
}
|
||||
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLORTEMPERATURE "\":%d"), mqtt_data, LightGetColorTemp());
|
||||
}
|
||||
if (append) {
|
||||
if (light_subtype >= LST_RGB) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_SCHEME "\":%d"), mqtt_data, Settings.light_scheme);
|
||||
}
|
||||
if (LT_WS2812 == light_type) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_WIDTH "\":%d"), mqtt_data, Settings.light_width);
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_FADE "\":\"%s\",\"" D_CMND_SPEED "\":%d,\"" D_CMND_LEDTABLE "\":\"%s\""),
|
||||
mqtt_data, GetStateText(Settings.light_fade), Settings.light_speed, GetStateText(Settings.light_correction));
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
}
|
||||
}
|
||||
|
||||
void LightPreparePower()
|
||||
{
|
||||
char scolor[25];
|
||||
char scommand[16];
|
||||
|
||||
if (Settings.light_dimmer && !(light_power)) {
|
||||
ExecuteCommandPower(devices_present, 7); // No publishPowerState
|
||||
if (!Settings.flag.not_power_linked) {
|
||||
ExecuteCommandPower(light_device, POWER_ON_NO_STATE);
|
||||
}
|
||||
}
|
||||
else if (!Settings.light_dimmer && light_power) {
|
||||
ExecuteCommandPower(devices_present, 6); // No publishPowerState
|
||||
ExecuteCommandPower(light_device, POWER_OFF_NO_STATE);
|
||||
}
|
||||
#ifdef USE_DOMOTICZ
|
||||
DomoticzUpdatePowerState(devices_present);
|
||||
DomoticzUpdatePowerState(light_device);
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
GetPowerDevice(scommand, devices_present, sizeof(scommand));
|
||||
if (light_subtype > LST_SINGLE) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d,\"" D_CMND_COLOR "\":\"%s\"}"),
|
||||
scommand, GetStateText(light_power), Settings.light_dimmer, LightGetColor(0, scolor));
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d}"),
|
||||
scommand, GetStateText(light_power), Settings.light_dimmer);
|
||||
}
|
||||
LightState(0);
|
||||
}
|
||||
|
||||
void LightFade()
|
||||
@ -636,7 +662,8 @@ void LightRandomColor()
|
||||
|
||||
void LightSetPower()
|
||||
{
|
||||
light_power = XdrvMailbox.index;
|
||||
// light_power = XdrvMailbox.index;
|
||||
light_power = bitRead(XdrvMailbox.index, light_device -1);
|
||||
if (light_wakeup_active) {
|
||||
light_wakeup_active--;
|
||||
}
|
||||
@ -649,7 +676,7 @@ void LightSetPower()
|
||||
void LightAnimate()
|
||||
{
|
||||
uint8_t cur_col[5];
|
||||
uint16_t light_still_on;
|
||||
uint16_t light_still_on = 0;
|
||||
|
||||
strip_timer_counter++;
|
||||
if (!light_power) { // Power Off
|
||||
@ -701,7 +728,7 @@ void LightAnimate()
|
||||
}
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\"}"));
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_CMND_WAKEUP));
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_CMND_WAKEUP));
|
||||
light_wakeup_active = 0;
|
||||
Settings.light_scheme = LS_POWER;
|
||||
}
|
||||
@ -865,21 +892,6 @@ void LightHsbToRgb()
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void LightReplaceHsb(String *response)
|
||||
{
|
||||
if (light_subtype > LST_COLDWARM) {
|
||||
LightRgbToHsb();
|
||||
response->replace("{h}", String((uint16_t)(65535.0f * light_hue)));
|
||||
response->replace("{s}", String((uint8_t)(254.0f * light_saturation)));
|
||||
response->replace("{b}", String((uint8_t)(254.0f * light_brightness)));
|
||||
} else {
|
||||
response->replace("{h}", "0");
|
||||
response->replace("{s}", "0");
|
||||
// response->replace("{b}", String((uint8_t)(2.54f * (float)Settings.light_dimmer)));
|
||||
response->replace("{b}", String((uint8_t)(0.01f * (float)Settings.light_dimmer)));
|
||||
}
|
||||
}
|
||||
|
||||
void LightGetHsb(float *hue, float *sat, float *bri)
|
||||
{
|
||||
if (light_subtype > LST_COLDWARM) {
|
||||
@ -908,7 +920,7 @@ void LightSetHsb(float hue, float sat, float bri, uint16_t ct)
|
||||
LightSetColor();
|
||||
}
|
||||
LightPreparePower();
|
||||
MqttPublishPrefixTopic_P(5, PSTR(D_CMND_COLOR));
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_COLOR));
|
||||
} else {
|
||||
uint8_t tmp = (uint8_t)(bri * 100);
|
||||
Settings.light_dimmer = tmp;
|
||||
@ -917,10 +929,10 @@ void LightSetHsb(float hue, float sat, float bri, uint16_t ct)
|
||||
LightSetColorTemp(ct);
|
||||
}
|
||||
LightPreparePower();
|
||||
MqttPublishPrefixTopic_P(5, PSTR(D_CMND_COLOR));
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_COLOR));
|
||||
} else {
|
||||
LightPreparePower();
|
||||
MqttPublishPrefixTopic_P(5, PSTR(D_CMND_DIMMER));
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_DIMMER));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -962,7 +974,8 @@ boolean LightColorEntry(char *buffer, uint8_t buffer_length)
|
||||
light_entry_color[i++] = atoi(str);
|
||||
}
|
||||
}
|
||||
entry_type = (light_subtype == i) ? 2 : 0; // Decimal
|
||||
// entry_type = (light_subtype == i) ? 2 : 0; // Decimal
|
||||
entry_type = 2; // Decimal
|
||||
}
|
||||
else if ((2 * light_subtype) == buffer_length) { // Hexadecimal entry
|
||||
for (byte i = 0; i < light_subtype; i++) {
|
||||
@ -1181,7 +1194,7 @@ boolean LightCommand()
|
||||
scolor[6] = '\0'; // RGB only
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,%d,%d,%d,%d,%d"),
|
||||
scolor, Settings.light_fade, Settings.light_correction, Settings.light_scheme, Settings.light_speed, Settings.light_width);
|
||||
MqttPublishPrefixTopic_P(1, XdrvMailbox.topic);
|
||||
MqttPublishPrefixTopic_P(STAT, XdrvMailbox.topic);
|
||||
mqtt_data[0] = '\0';
|
||||
}
|
||||
else {
|
||||
@ -1211,11 +1224,14 @@ boolean Xdrv01(byte function)
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
LightAnimate();
|
||||
#ifdef USE_ARILUX_RF
|
||||
if (pin[GPIO_ARIRFRCV] < 99) {
|
||||
AriluxRfHandler();
|
||||
}
|
||||
if (pin[GPIO_ARIRFRCV] < 99) AriluxRfHandler();
|
||||
#endif // USE_ARILUX_RF
|
||||
break;
|
||||
#ifdef USE_ARILUX_RF
|
||||
case FUNC_EVERY_SECOND:
|
||||
if (10 == uptime) AriluxRfInit(); // Needs rest before enabling RF interrupts
|
||||
break;
|
||||
#endif // USE_ARILUX_RF
|
||||
case FUNC_COMMAND:
|
||||
result = LightCommand();
|
||||
break;
|
||||
|
||||
@ -107,9 +107,9 @@ void IrReceiveCheck()
|
||||
if ((iridx < 0) || (iridx > 14)) {
|
||||
iridx = 0;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_IRRECEIVED "\":{\"" D_JSON_IR_PROTOCOL "\":\"%s\",\"" D_JSON_IR_BITS "\":%d,\"" D_JSON_IR_DATA "\":\"%X\"}}"),
|
||||
GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, results.value);
|
||||
MqttPublishPrefixTopic_P(6, PSTR(D_JSON_IRRECEIVED));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_IRRECEIVED "\":{\"" D_JSON_IR_PROTOCOL "\":\"%s\",\"" D_JSON_IR_BITS "\":%d,\"" D_JSON_IR_DATA "\":\"%lX\"}}"),
|
||||
GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, (uint32_t)results.value);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED));
|
||||
#ifdef USE_DOMOTICZ
|
||||
unsigned long value = results.value | (iridx << 28); // [Protocol:4, Data:28]
|
||||
DomoticzSensor(DZ_COUNT, value); // Send data as Domoticz Counter value
|
||||
@ -132,7 +132,6 @@ boolean IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean H
|
||||
byte data[HVAC_TOSHIBA_DATALEN] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
char *p;
|
||||
char *token;
|
||||
uint8_t mode;
|
||||
|
||||
if (HVAC_Mode == NULL) {
|
||||
@ -176,7 +175,7 @@ boolean IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean H
|
||||
else {
|
||||
Temp = HVAC_Temp;
|
||||
}
|
||||
data[5] = (byte)Temp - 17 << 4;
|
||||
data[5] = (byte)(Temp - 17) << 4;
|
||||
|
||||
data[HVAC_TOSHIBA_DATALEN - 1] = 0;
|
||||
for (int x = 0; x < HVAC_TOSHIBA_DATALEN - 1; x++) {
|
||||
@ -219,7 +218,6 @@ boolean IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean H
|
||||
boolean IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, boolean HVAC_Power, int HVAC_Temp)
|
||||
{
|
||||
char *p;
|
||||
char *token;
|
||||
uint8_t mode;
|
||||
|
||||
mitsubir->stateReset();
|
||||
@ -286,12 +284,6 @@ boolean IrSendCommand()
|
||||
uint32_t bits = 0;
|
||||
uint32_t data = 0;
|
||||
|
||||
const char *HVAC_Mode;
|
||||
const char *HVAC_FanMode;
|
||||
const char *HVAC_Vendor;
|
||||
int HVAC_Temp = 21;
|
||||
boolean HVAC_Power = true;
|
||||
|
||||
for (uint16_t i = 0; i <= sizeof(dataBufUc); i++) {
|
||||
dataBufUc[i] = toupper(XdrvMailbox.data[i]);
|
||||
}
|
||||
@ -309,21 +301,26 @@ boolean IrSendCommand()
|
||||
data = ir_json[D_JSON_IR_DATA];
|
||||
if (protocol && bits && data) {
|
||||
int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols);
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %d, protocol_code %d"),
|
||||
protocol_text, protocol, bits, data, protocol_code);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
switch (protocol_code) {
|
||||
case NEC:
|
||||
irsend->sendNEC(data, bits); break;
|
||||
irsend->sendNEC(data, (bits > NEC_BITS) ? NEC_BITS : bits); break;
|
||||
case SONY:
|
||||
irsend->sendSony(data, bits); break;
|
||||
irsend->sendSony(data, (bits > SONY_20_BITS) ? SONY_20_BITS : bits, 2); break;
|
||||
case RC5:
|
||||
irsend->sendRC5(data, bits); break;
|
||||
case RC6:
|
||||
irsend->sendRC6(data, bits); break;
|
||||
case DISH:
|
||||
irsend->sendDISH(data, bits); break;
|
||||
irsend->sendDISH(data, (bits > DISH_BITS) ? DISH_BITS : bits); break;
|
||||
case JVC:
|
||||
irsend->sendJVC(data, bits, 1); break;
|
||||
irsend->sendJVC(data, (bits > JVC_BITS) ? JVC_BITS : bits, 1); break;
|
||||
case SAMSUNG:
|
||||
irsend->sendSAMSUNG(data, bits); break;
|
||||
irsend->sendSAMSUNG(data, (bits > SAMSUNG_BITS) ? SAMSUNG_BITS : bits); break;
|
||||
case PANASONIC:
|
||||
irsend->sendPanasonic(bits, data); break;
|
||||
default:
|
||||
@ -344,6 +341,12 @@ boolean IrSendCommand()
|
||||
}
|
||||
#ifdef USE_IR_HVAC
|
||||
else if (!strcasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_IRHVAC))) {
|
||||
const char *HVAC_Mode;
|
||||
const char *HVAC_FanMode;
|
||||
const char *HVAC_Vendor;
|
||||
int HVAC_Temp = 21;
|
||||
boolean HVAC_Power = true;
|
||||
|
||||
if (XdrvMailbox.data_len) {
|
||||
StaticJsonBuffer<164> jsonBufer;
|
||||
JsonObject &root = jsonBufer.parseObject(dataBufUc);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
xsns_03_energy.ino - HLW8012 (Sonoff Pow) and PZEM004T energy sensor support for Sonoff-Tasmota
|
||||
xdrv_03_energy.ino - HLW8012 (Sonoff Pow) and PZEM004T energy sensor support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends
|
||||
|
||||
@ -26,17 +26,17 @@
|
||||
|
||||
#define FEATURE_POWER_LIMIT true
|
||||
|
||||
enum EnergyHardware { ENERGY_NONE, ENERGY_HLW8012, ENERGY_PZEM004T };
|
||||
enum EnergyHardware { ENERGY_NONE, ENERGY_HLW8012, ENERGY_CSE7766, ENERGY_PZEM004T };
|
||||
|
||||
enum EnergyCommands {
|
||||
CMND_POWERLOW, CMND_POWERHIGH, CMND_VOLTAGELOW, CMND_VOLTAGEHIGH, CMND_CURRENTLOW, CMND_CURRENTHIGH,
|
||||
CMND_HLWPCAL, CMND_HLWPSET, CMND_HLWUCAL, CMND_HLWUSET, CMND_HLWICAL, CMND_HLWISET,
|
||||
CMND_POWERCAL, CMND_POWERSET, CMND_VOLTAGECAL, CMND_VOLTAGESET, CMND_CURRENTCAL, CMND_CURRENTSET,
|
||||
CMND_ENERGYRESET, CMND_MAXENERGY, CMND_MAXENERGYSTART,
|
||||
CMND_MAXPOWER, CMND_MAXPOWERHOLD, CMND_MAXPOWERWINDOW,
|
||||
CMND_SAFEPOWER, CMND_SAFEPOWERHOLD, CMND_SAFEPOWERWINDOW };
|
||||
const char kEnergyCommands[] PROGMEM =
|
||||
D_CMND_POWERLOW "|" D_CMND_POWERHIGH "|" D_CMND_VOLTAGELOW "|" D_CMND_VOLTAGEHIGH "|" D_CMND_CURRENTLOW "|" D_CMND_CURRENTHIGH "|"
|
||||
D_CMND_HLWPCAL "|" D_CMND_HLWPSET "|" D_CMND_HLWUCAL "|" D_CMND_HLWUSET "|" D_CMND_HLWICAL "|" D_CMND_HLWISET "|"
|
||||
D_CMND_POWERCAL "|" D_CMND_POWERSET "|" D_CMND_VOLTAGECAL "|" D_CMND_VOLTAGESET "|" D_CMND_CURRENTCAL "|" D_CMND_CURRENTSET "|"
|
||||
D_CMND_ENERGYRESET "|" D_CMND_MAXENERGY "|" D_CMND_MAXENERGYSTART "|"
|
||||
D_CMND_MAXPOWER "|" D_CMND_MAXPOWERHOLD "|" D_CMND_MAXPOWERWINDOW "|"
|
||||
D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW ;
|
||||
@ -47,9 +47,11 @@ float energy_power = 0; // 123.1 W
|
||||
float energy_power_factor = 0; // 0.12
|
||||
float energy_daily = 0; // 12.123 kWh
|
||||
float energy_total = 0; // 12345.12345 kWh
|
||||
float energy_start = 0; // 12345.12345 kWh total from yesterday
|
||||
float energy_start = 0; // 12345.12345 kWh total previous
|
||||
unsigned long energy_kWhtoday; // 1212312345 Wh * 10^-5 (deca micro Watt hours) - 5763924 = 0.05763924 kWh = 0.058 kWh = energy_daily
|
||||
unsigned long energy_period = 0; //
|
||||
unsigned long energy_period = 0; // 1212312345 Wh * 10^-5 (deca micro Watt hours) - 5763924 = 0.05763924 kWh = 0.058 kWh = energy_daily
|
||||
|
||||
bool energy_power_on = true;
|
||||
|
||||
byte energy_min_power_flag = 0;
|
||||
byte energy_max_power_flag = 0;
|
||||
@ -67,12 +69,20 @@ uint16_t energy_mplh_counter = 0;
|
||||
uint16_t energy_mplw_counter = 0;
|
||||
#endif // FEATURE_POWER_LIMIT
|
||||
|
||||
byte energy_startup = 1;
|
||||
byte energy_fifth_second = 0;
|
||||
Ticker ticker_energy;
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void EnergyUpdateToday()
|
||||
{
|
||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
||||
energy_daily = (float)energy_kWhtoday / 100000000;
|
||||
energy_total = (float)(RtcSettings.energy_kWhtotal + (energy_kWhtoday / 1000)) / 100000;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* HLW8012 - Energy
|
||||
* HLW8012 - Energy (Sonoff Pow)
|
||||
*
|
||||
* Based on Source: Shenzhen Heli Technology Co., Ltd
|
||||
\*********************************************************************************************/
|
||||
@ -136,18 +146,13 @@ void HlwCf1Interrupt() // Service Voltage and Current
|
||||
void HlwEverySecond()
|
||||
{
|
||||
unsigned long hlw_len;
|
||||
unsigned long hlw_temp;
|
||||
|
||||
if (hlw_energy_period_counter) {
|
||||
hlw_len = 10000 / hlw_energy_period_counter;
|
||||
hlw_energy_period_counter = 0;
|
||||
if (hlw_len) {
|
||||
hlw_temp = ((HLW_PREF * Settings.hlw_power_calibration) / hlw_len) / 36;
|
||||
energy_kWhtoday += hlw_temp;
|
||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
||||
|
||||
energy_total = (float)(RtcSettings.energy_kWhtotal + (energy_kWhtoday / 1000)) / 100000;
|
||||
energy_daily = (float)energy_kWhtoday / 100000000;
|
||||
energy_kWhtoday += ((HLW_PREF * Settings.energy_power_calibration) / hlw_len) / 36;
|
||||
EnergyUpdateToday();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,8 +168,8 @@ void HlwEvery200ms()
|
||||
hlw_load_off = 1;
|
||||
}
|
||||
|
||||
if (hlw_cf_pulse_length && (power &1) && !hlw_load_off) {
|
||||
hlw_w = (HLW_PREF * Settings.hlw_power_calibration) / hlw_cf_pulse_length;
|
||||
if (hlw_cf_pulse_length && energy_power_on && !hlw_load_off) {
|
||||
hlw_w = (HLW_PREF * Settings.energy_power_calibration) / hlw_cf_pulse_length;
|
||||
energy_power = (float)hlw_w / 10;
|
||||
} else {
|
||||
energy_power = 0;
|
||||
@ -185,8 +190,8 @@ void HlwEvery200ms()
|
||||
hlw_cf1_voltage_pulse_length = hlw_cf1_pulse_length;
|
||||
hlw_cf1_voltage_max_pulse_counter = hlw_cf1_pulse_counter;
|
||||
|
||||
if (hlw_cf1_voltage_pulse_length && (power &1)) { // If powered on always provide voltage
|
||||
hlw_u = (HLW_UREF * Settings.hlw_voltage_calibration) / hlw_cf1_voltage_pulse_length;
|
||||
if (hlw_cf1_voltage_pulse_length && energy_power_on) { // If powered on always provide voltage
|
||||
hlw_u = (HLW_UREF * Settings.energy_voltage_calibration) / hlw_cf1_voltage_pulse_length;
|
||||
energy_voltage = (float)hlw_u / 10;
|
||||
} else {
|
||||
energy_voltage = 0;
|
||||
@ -197,7 +202,7 @@ void HlwEvery200ms()
|
||||
hlw_cf1_current_max_pulse_counter = hlw_cf1_pulse_counter;
|
||||
|
||||
if (hlw_cf1_current_pulse_length && energy_power) { // No current if no power being consumed
|
||||
hlw_i = (HLW_IREF * Settings.hlw_current_calibration) / hlw_cf1_current_pulse_length;
|
||||
hlw_i = (HLW_IREF * Settings.energy_current_calibration) / hlw_cf1_current_pulse_length;
|
||||
energy_current = (float)hlw_i / 1000;
|
||||
} else {
|
||||
energy_current = 0;
|
||||
@ -211,10 +216,10 @@ void HlwEvery200ms()
|
||||
|
||||
void HlwInit()
|
||||
{
|
||||
if (!Settings.hlw_power_calibration || (4975 == Settings.hlw_power_calibration)) {
|
||||
Settings.hlw_power_calibration = HLW_PREF_PULSE;
|
||||
Settings.hlw_voltage_calibration = HLW_UREF_PULSE;
|
||||
Settings.hlw_current_calibration = HLW_IREF_PULSE;
|
||||
if (!Settings.energy_power_calibration || (4975 == Settings.energy_power_calibration)) {
|
||||
Settings.energy_power_calibration = HLW_PREF_PULSE;
|
||||
Settings.energy_voltage_calibration = HLW_UREF_PULSE;
|
||||
Settings.energy_current_calibration = HLW_IREF_PULSE;
|
||||
}
|
||||
|
||||
hlw_cf_pulse_length = 0;
|
||||
@ -241,6 +246,145 @@ void HlwInit()
|
||||
hlw_cf1_timer = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* CSE7766 - Energy (Sonoff S31)
|
||||
*
|
||||
* Based on datasheet from http://www.chipsea.com/UploadFiles/2017/08/11144342F01B5662.pdf
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define CSE_NOT_CALIBRATED 0xAA
|
||||
|
||||
#define CSE_PULSES_NOT_INITIALIZED -1
|
||||
|
||||
#define CSE_PREF 1000
|
||||
#define CSE_UREF 100
|
||||
|
||||
uint8_t cse_receive_flag = 0;
|
||||
|
||||
long voltage_cycle = 0;
|
||||
long current_cycle = 0;
|
||||
long power_cycle = 0;
|
||||
long cf_pulses = 0;
|
||||
long cf_pulses_last_time = CSE_PULSES_NOT_INITIALIZED;
|
||||
|
||||
void CseReceived()
|
||||
{
|
||||
AddLogSerial(LOG_LEVEL_DEBUG_MORE);
|
||||
|
||||
uint8_t header = serial_in_buffer[0];
|
||||
if ((header & 0xFC) == 0xFC) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Abnormal hardware"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate checksum
|
||||
uint8_t checksum = 0;
|
||||
for (byte i = 2; i < 23; i++) checksum += serial_in_buffer[i];
|
||||
if (checksum != serial_in_buffer[23]) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: " D_CHECKSUM_FAILURE));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get chip calibration data (coefficients) and use as initial defaults
|
||||
if (HLW_UREF_PULSE == Settings.energy_voltage_calibration) {
|
||||
long voltage_coefficient = 191200; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
voltage_coefficient = serial_in_buffer[2] << 16 | serial_in_buffer[3] << 8 | serial_in_buffer[4];
|
||||
}
|
||||
Settings.energy_voltage_calibration = voltage_coefficient / CSE_UREF;
|
||||
}
|
||||
if (HLW_IREF_PULSE == Settings.energy_current_calibration) {
|
||||
long current_coefficient = 16140; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
current_coefficient = serial_in_buffer[8] << 16 | serial_in_buffer[9] << 8 | serial_in_buffer[10];
|
||||
}
|
||||
Settings.energy_current_calibration = current_coefficient;
|
||||
}
|
||||
if (HLW_PREF_PULSE == Settings.energy_power_calibration) {
|
||||
long power_coefficient = 5364000; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
power_coefficient = serial_in_buffer[14] << 16 | serial_in_buffer[15] << 8 | serial_in_buffer[16];
|
||||
}
|
||||
Settings.energy_power_calibration = power_coefficient / CSE_PREF;
|
||||
}
|
||||
|
||||
uint8_t adjustement = serial_in_buffer[20];
|
||||
voltage_cycle = serial_in_buffer[5] << 16 | serial_in_buffer[6] << 8 | serial_in_buffer[7];
|
||||
current_cycle = serial_in_buffer[11] << 16 | serial_in_buffer[12] << 8 | serial_in_buffer[13];
|
||||
power_cycle = serial_in_buffer[17] << 16 | serial_in_buffer[18] << 8 | serial_in_buffer[19];
|
||||
cf_pulses = serial_in_buffer[21] << 8 | serial_in_buffer[22];
|
||||
|
||||
// if (adjustement & 0x80) { // CF overflow
|
||||
// cf_pulses += 0x10000;
|
||||
// }
|
||||
if (energy_power_on) { // Powered on
|
||||
if (adjustement & 0x40) { // Voltage valid
|
||||
energy_voltage = (float)(Settings.energy_voltage_calibration * CSE_UREF) / (float)voltage_cycle;
|
||||
}
|
||||
if (adjustement & 0x10) { // Power valid
|
||||
if ((header & 0xF2) == 0xF2) { // Power cycle exceeds range
|
||||
energy_power = 0;
|
||||
} else {
|
||||
energy_power = (float)(Settings.energy_power_calibration * CSE_PREF) / (float)power_cycle;
|
||||
}
|
||||
} else {
|
||||
energy_power = 0; // Powered on but no load
|
||||
}
|
||||
if (adjustement & 0x20) { // Current valid
|
||||
if (0 == energy_power) {
|
||||
energy_current = 0;
|
||||
} else {
|
||||
energy_current = (float)Settings.energy_current_calibration / (float)current_cycle;
|
||||
}
|
||||
}
|
||||
} else { // Powered off
|
||||
energy_voltage = 0;
|
||||
energy_power = 0;
|
||||
energy_current = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CseSerialInput()
|
||||
{
|
||||
if (cse_receive_flag) {
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
if (24 == serial_in_byte_counter) {
|
||||
CseReceived();
|
||||
cse_receive_flag = 0;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (0x5A == serial_in_byte) { // 0x5A - Packet header 2
|
||||
cse_receive_flag = 1;
|
||||
} else {
|
||||
serial_in_byte_counter = 0;
|
||||
}
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
}
|
||||
serial_in_byte = 0; // Discard
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CseEverySecond()
|
||||
{
|
||||
long cf_frequency = 0;
|
||||
|
||||
if (CSE_PULSES_NOT_INITIALIZED == cf_pulses_last_time) {
|
||||
cf_pulses_last_time = cf_pulses; // Init after restart
|
||||
} else {
|
||||
if (cf_pulses < cf_pulses_last_time) { // Rolled over after 65535 pulses
|
||||
cf_frequency = (65536 - cf_pulses_last_time) + cf_pulses;
|
||||
} else {
|
||||
cf_frequency = cf_pulses - cf_pulses_last_time;
|
||||
}
|
||||
if (cf_frequency && energy_power) {
|
||||
cf_pulses_last_time = cf_pulses;
|
||||
energy_kWhtoday += (cf_frequency * Settings.energy_power_calibration) / 36;
|
||||
EnergyUpdateToday();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_PZEM004T
|
||||
/*********************************************************************************************\
|
||||
* PZEM004T - Energy
|
||||
@ -285,9 +429,7 @@ IPAddress pzem_ip(192, 168, 1, 1);
|
||||
uint8_t PzemCrc(uint8_t *data)
|
||||
{
|
||||
uint16_t crc = 0;
|
||||
for (uint8_t i = 0; i < sizeof(PZEMCommand) -1; i++) {
|
||||
crc += *data++;
|
||||
}
|
||||
for (uint8_t i = 0; i < sizeof(PZEMCommand) -1; i++) crc += *data++;
|
||||
return (uint8_t)(crc & 0xFF);
|
||||
}
|
||||
|
||||
@ -296,20 +438,19 @@ void PzemSend(uint8_t cmd)
|
||||
PZEMCommand pzem;
|
||||
|
||||
pzem.command = cmd;
|
||||
for (int i = 0; i < sizeof(pzem.addr); i++) {
|
||||
pzem.addr[i] = pzem_ip[i];
|
||||
}
|
||||
for (uint8_t i = 0; i < sizeof(pzem.addr); i++) pzem.addr[i] = pzem_ip[i];
|
||||
pzem.data = 0;
|
||||
|
||||
uint8_t *bytes = (uint8_t*)&pzem;
|
||||
pzem.crc = PzemCrc(bytes);
|
||||
|
||||
PzemSerial->flush();
|
||||
PzemSerial->write(bytes, sizeof(pzem));
|
||||
}
|
||||
|
||||
bool PzemReceiveReady()
|
||||
{
|
||||
return PzemSerial->available() >= sizeof(PZEMCommand);
|
||||
return PzemSerial->available() >= (int)sizeof(PZEMCommand);
|
||||
}
|
||||
|
||||
bool PzemRecieve(uint8_t resp, float *data)
|
||||
@ -374,31 +515,24 @@ void PzemEvery200ms()
|
||||
float value = 0;
|
||||
if (PzemRecieve(pzem_responses[pzem_read_state], &value)) {
|
||||
switch (pzem_read_state) {
|
||||
case 1:
|
||||
energy_voltage = value; // 230.2V
|
||||
case 1: // Voltage as 230.2V
|
||||
energy_voltage = value;
|
||||
break;
|
||||
case 2:
|
||||
energy_current = value; // 17.32A
|
||||
case 2: // Current as 17.32A
|
||||
energy_current = value;
|
||||
break;
|
||||
case 3:
|
||||
energy_power = value; // 20W
|
||||
case 3: // Power as 20W
|
||||
energy_power = value;
|
||||
break;
|
||||
case 4:
|
||||
energy_total = value / 1000; // 99999Wh
|
||||
if (!energy_startup) {
|
||||
if (energy_total < energy_start) {
|
||||
energy_start = energy_total;
|
||||
Settings.hlw_power_calibration = energy_start * 1000;
|
||||
}
|
||||
energy_kWhtoday = (energy_total - energy_start) * 100000000;
|
||||
energy_daily = (float)energy_kWhtoday / 100000000;
|
||||
}
|
||||
case 4: // Total energy as 99999Wh
|
||||
if (!energy_start || (value < energy_start)) energy_start = value; // Init after restart and hanlde roll-over if any
|
||||
energy_kWhtoday += (value - energy_start) * 100000;
|
||||
energy_start = value;
|
||||
EnergyUpdateToday();
|
||||
break;
|
||||
}
|
||||
pzem_read_state++;
|
||||
if (5 == pzem_read_state) {
|
||||
pzem_read_state = 1;
|
||||
}
|
||||
if (5 == pzem_read_state) pzem_read_state = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,9 +560,8 @@ void Energy200ms()
|
||||
if (5 == energy_fifth_second) {
|
||||
energy_fifth_second = 0;
|
||||
|
||||
if (ENERGY_HLW8012 == energy_flg) {
|
||||
HlwEverySecond();
|
||||
}
|
||||
if (ENERGY_HLW8012 == energy_flg) HlwEverySecond();
|
||||
if (ENERGY_CSE7766 == energy_flg) CseEverySecond();
|
||||
|
||||
if (RtcTime.valid) {
|
||||
if (LocalTime() == Midnight()) {
|
||||
@ -436,42 +569,27 @@ void Energy200ms()
|
||||
Settings.energy_kWhtotal += (energy_kWhtoday / 1000);
|
||||
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
|
||||
energy_kWhtoday = 0;
|
||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
||||
#ifdef USE_PZEM004T
|
||||
if (ENERGY_PZEM004T == energy_flg) {
|
||||
energy_start = energy_total;
|
||||
Settings.hlw_power_calibration = energy_start * 1000;
|
||||
}
|
||||
#endif // USE_PZEM004T
|
||||
energy_period = energy_kWhtoday;
|
||||
EnergyUpdateToday();
|
||||
energy_max_energy_state = 3;
|
||||
}
|
||||
if ((RtcTime.hour == Settings.energy_max_energy_start) && (3 == energy_max_energy_state)) {
|
||||
energy_max_energy_state = 0;
|
||||
}
|
||||
if (energy_startup && (RtcTime.day_of_year == Settings.energy_kWhdoy)) {
|
||||
energy_kWhtoday = Settings.energy_kWhtoday;
|
||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
||||
energy_start = (float)Settings.hlw_power_calibration / 1000; // Used by PZEM004T to store total yesterday
|
||||
energy_startup = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ENERGY_HLW8012 == energy_flg) {
|
||||
HlwEvery200ms();
|
||||
energy_power_on = (power &1) | Settings.flag.no_power_on_check;
|
||||
|
||||
if (ENERGY_HLW8012 == energy_flg) HlwEvery200ms();
|
||||
#ifdef USE_PZEM004T
|
||||
}
|
||||
else if (ENERGY_PZEM004T == energy_flg) {
|
||||
PzemEvery200ms();
|
||||
if (ENERGY_PZEM004T == energy_flg) PzemEvery200ms();
|
||||
#endif // USE_PZEM004T
|
||||
}
|
||||
|
||||
float power_factor = 0;
|
||||
if (energy_voltage && energy_current && energy_power) {
|
||||
power_factor = energy_power / (energy_voltage * energy_current);
|
||||
if (power_factor > 1) {
|
||||
power_factor = 1;
|
||||
}
|
||||
if (power_factor > 1) power_factor = 1;
|
||||
}
|
||||
energy_power_factor = power_factor;
|
||||
}
|
||||
@ -480,6 +598,7 @@ void EnergySaveState()
|
||||
{
|
||||
Settings.energy_kWhdoy = (RtcTime.valid) ? RtcTime.day_of_year : 0;
|
||||
Settings.energy_kWhtoday = energy_kWhtoday;
|
||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
||||
Settings.energy_kWhtotal = RtcSettings.energy_kWhtotal;
|
||||
}
|
||||
|
||||
@ -487,9 +606,7 @@ boolean EnergyMargin(byte type, uint16_t margin, uint16_t value, byte &flag, byt
|
||||
{
|
||||
byte change;
|
||||
|
||||
if (!margin) {
|
||||
return false;
|
||||
}
|
||||
if (!margin) return false;
|
||||
change = save_flag;
|
||||
if (type) {
|
||||
flag = (value > margin);
|
||||
@ -507,10 +624,10 @@ void EnergySetPowerSteadyCounter()
|
||||
|
||||
void EnergyMarginCheck()
|
||||
{
|
||||
uint16_t energy_daily_u;
|
||||
uint16_t energy_power_u;
|
||||
uint16_t energy_voltage_u;
|
||||
uint16_t energy_current_u;
|
||||
uint16_t energy_daily_u = 0;
|
||||
uint16_t energy_power_u = 0;
|
||||
uint16_t energy_voltage_u = 0;
|
||||
uint16_t energy_current_u = 0;
|
||||
boolean flag;
|
||||
boolean jsonflg;
|
||||
|
||||
@ -519,7 +636,7 @@ void EnergyMarginCheck()
|
||||
return;
|
||||
}
|
||||
|
||||
if (power && (Settings.energy_min_power || Settings.energy_max_power || Settings.energy_min_voltage || Settings.energy_max_voltage || Settings.energy_min_current || Settings.energy_max_current)) {
|
||||
if (energy_power_on && (Settings.energy_min_power || Settings.energy_max_power || Settings.energy_min_voltage || Settings.energy_max_voltage || Settings.energy_min_current || Settings.energy_max_current)) {
|
||||
energy_power_u = (uint16_t)(energy_power);
|
||||
energy_voltage_u = (uint16_t)(energy_voltage);
|
||||
energy_current_u = (uint16_t)(energy_current * 1000);
|
||||
@ -555,7 +672,7 @@ void EnergyMarginCheck()
|
||||
}
|
||||
if (jsonflg) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_MARGINS));
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_MARGINS));
|
||||
EnergyMqttShow();
|
||||
}
|
||||
}
|
||||
@ -570,9 +687,9 @@ void EnergyMarginCheck()
|
||||
energy_mplh_counter--;
|
||||
if (!energy_mplh_counter) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHED "\":\"%d%s\"}"), energy_power_u, (Settings.flag.value_units) ? " " D_UNIT_WATT : "");
|
||||
MqttPublishPrefixTopic_P(1, S_RSLT_WARNING);
|
||||
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
||||
EnergyMqttShow();
|
||||
ExecuteCommandPower(1, 0);
|
||||
ExecuteCommandPower(1, POWER_OFF);
|
||||
if (!energy_mplr_counter) {
|
||||
energy_mplr_counter = Settings.param[P_MAX_POWER_RETRY] +1;
|
||||
}
|
||||
@ -593,11 +710,11 @@ void EnergyMarginCheck()
|
||||
energy_mplr_counter--;
|
||||
if (energy_mplr_counter) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_POWERMONITOR "\":\"%s\"}"), GetStateText(1));
|
||||
MqttPublishPrefixTopic_P(5, PSTR(D_JSON_POWERMONITOR));
|
||||
ExecuteCommandPower(1, 1);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_POWERMONITOR));
|
||||
ExecuteCommandPower(1, POWER_ON);
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHEDRETRY "\":\"%s\"}"), GetStateText(0));
|
||||
MqttPublishPrefixTopic_P(1, S_RSLT_WARNING);
|
||||
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
||||
EnergyMqttShow();
|
||||
}
|
||||
}
|
||||
@ -611,16 +728,16 @@ void EnergyMarginCheck()
|
||||
if (!energy_max_energy_state && (RtcTime.hour == Settings.energy_max_energy_start)) {
|
||||
energy_max_energy_state = 1;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_ENERGYMONITOR "\":\"%s\"}"), GetStateText(1));
|
||||
MqttPublishPrefixTopic_P(5, PSTR(D_JSON_ENERGYMONITOR));
|
||||
ExecuteCommandPower(1, 1);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_ENERGYMONITOR));
|
||||
ExecuteCommandPower(1, POWER_ON);
|
||||
}
|
||||
else if ((1 == energy_max_energy_state) && (energy_daily_u >= Settings.energy_max_energy)) {
|
||||
energy_max_energy_state = 2;
|
||||
dtostrfd(energy_daily, 3, mqtt_data);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXENERGYREACHED "\":\"%s%s\"}"), mqtt_data, (Settings.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : "");
|
||||
MqttPublishPrefixTopic_P(1, S_RSLT_WARNING);
|
||||
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
|
||||
EnergyMqttShow();
|
||||
ExecuteCommandPower(1, 0);
|
||||
ExecuteCommandPower(1, POWER_OFF);
|
||||
}
|
||||
}
|
||||
#endif // FEATURE_POWER_LIMIT
|
||||
@ -631,7 +748,8 @@ void EnergyMqttShow()
|
||||
// {"Time":"2017-12-16T11:48:55","ENERGY":{"Total":0.212,"Yesterday":0.000,"Today":0.014,"Period":2.0,"Power":22.0,"Factor":1.00,"Voltage":213.6,"Current":0.100}}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime().c_str());
|
||||
EnergyShow(1);
|
||||
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -697,8 +815,10 @@ boolean EnergyCommand()
|
||||
switch (XdrvMailbox.index) {
|
||||
case 1:
|
||||
energy_kWhtoday = lnum *100000;
|
||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
||||
energy_period = energy_kWhtoday;
|
||||
Settings.energy_kWhtoday = energy_kWhtoday;
|
||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
||||
energy_daily = (float)energy_kWhtoday / 100000000;
|
||||
break;
|
||||
case 2:
|
||||
Settings.energy_kWhyesterday = lnum *100000;
|
||||
@ -719,51 +839,68 @@ boolean EnergyCommand()
|
||||
command, energy_total_chr, energy_yesterday_chr, stoday_energy);
|
||||
status_flag = 1;
|
||||
}
|
||||
else if ((ENERGY_HLW8012 == energy_flg) && (CMND_HLWPCAL == command_code)) {
|
||||
|
||||
else if (((ENERGY_HLW8012 == energy_flg) || (ENERGY_CSE7766 == energy_flg)) && (CMND_POWERCAL == command_code)) {
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 32001)) {
|
||||
Settings.hlw_power_calibration = (XdrvMailbox.payload > 4000) ? XdrvMailbox.payload : HLW_PREF_PULSE; // 12530
|
||||
Settings.energy_power_calibration = (XdrvMailbox.payload > 4000) ? XdrvMailbox.payload : HLW_PREF_PULSE; // HLW = 12530, CSE = 5364
|
||||
}
|
||||
nvalue = Settings.hlw_power_calibration;
|
||||
nvalue = Settings.energy_power_calibration;
|
||||
unit = UNIT_MICROSECOND;
|
||||
}
|
||||
else if ((ENERGY_HLW8012 == energy_flg) && (CMND_HLWPSET == command_code)) {
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 3601) && hlw_cf_pulse_length) {
|
||||
Settings.hlw_power_calibration = (XdrvMailbox.payload * 10 * hlw_cf_pulse_length) / HLW_PREF;
|
||||
else if (((ENERGY_HLW8012 == energy_flg) || (ENERGY_CSE7766 == energy_flg)) && (CMND_POWERSET == command_code)) { // Watt
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 3601)) {
|
||||
if ((ENERGY_HLW8012 == energy_flg) && hlw_cf_pulse_length) {
|
||||
Settings.energy_power_calibration = (XdrvMailbox.payload * 10 * hlw_cf_pulse_length) / HLW_PREF;
|
||||
}
|
||||
else if ((ENERGY_CSE7766 == energy_flg) && power_cycle) {
|
||||
Settings.energy_power_calibration = (XdrvMailbox.payload * power_cycle) / CSE_PREF;
|
||||
}
|
||||
}
|
||||
snprintf_P(command, sizeof(command), PSTR(D_CMND_HLWPCAL));
|
||||
nvalue = Settings.hlw_power_calibration;
|
||||
snprintf_P(command, sizeof(command), PSTR(D_CMND_POWERCAL));
|
||||
nvalue = Settings.energy_power_calibration;
|
||||
unit = UNIT_MICROSECOND;
|
||||
}
|
||||
else if ((ENERGY_HLW8012 == energy_flg) && (CMND_HLWUCAL == command_code)) {
|
||||
else if (((ENERGY_HLW8012 == energy_flg) || (ENERGY_CSE7766 == energy_flg)) && (CMND_VOLTAGECAL == command_code)) {
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 32001)) {
|
||||
Settings.hlw_voltage_calibration = (XdrvMailbox.payload > 999) ? XdrvMailbox.payload : HLW_UREF_PULSE; // 1950
|
||||
Settings.energy_voltage_calibration = (XdrvMailbox.payload > 999) ? XdrvMailbox.payload : HLW_UREF_PULSE; // HLW = 1950, CSE = 1912
|
||||
}
|
||||
nvalue = Settings.hlw_voltage_calibration;
|
||||
nvalue = Settings.energy_voltage_calibration;
|
||||
unit = UNIT_MICROSECOND;
|
||||
}
|
||||
else if ((ENERGY_HLW8012 == energy_flg) && (CMND_HLWUSET == command_code)) {
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 501) && hlw_cf1_voltage_pulse_length) {
|
||||
Settings.hlw_voltage_calibration = (XdrvMailbox.payload * 10 * hlw_cf1_voltage_pulse_length) / HLW_UREF;
|
||||
else if (((ENERGY_HLW8012 == energy_flg) || (ENERGY_CSE7766 == energy_flg)) && (CMND_VOLTAGESET == command_code)) { // Volt
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 501)) {
|
||||
if ((ENERGY_HLW8012 == energy_flg) && hlw_cf1_voltage_pulse_length) {
|
||||
Settings.energy_voltage_calibration = (XdrvMailbox.payload * 10 * hlw_cf1_voltage_pulse_length) / HLW_UREF;
|
||||
}
|
||||
else if ((ENERGY_CSE7766 == energy_flg) && voltage_cycle) {
|
||||
Settings.energy_voltage_calibration = (XdrvMailbox.payload * voltage_cycle) / CSE_UREF;
|
||||
}
|
||||
}
|
||||
snprintf_P(command, sizeof(command), PSTR(D_CMND_HLWUCAL));
|
||||
nvalue = Settings.hlw_voltage_calibration;
|
||||
snprintf_P(command, sizeof(command), PSTR(D_CMND_VOLTAGECAL));
|
||||
nvalue = Settings.energy_voltage_calibration;
|
||||
unit = UNIT_MICROSECOND;
|
||||
}
|
||||
else if ((ENERGY_HLW8012 == energy_flg) && (CMND_HLWICAL == command_code)) {
|
||||
else if (((ENERGY_HLW8012 == energy_flg) || (ENERGY_CSE7766 == energy_flg)) && (CMND_CURRENTCAL == command_code)) {
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 32001)) {
|
||||
Settings.hlw_current_calibration = (XdrvMailbox.payload > 1100) ? XdrvMailbox.payload : HLW_IREF_PULSE; // 3500
|
||||
Settings.energy_current_calibration = (XdrvMailbox.payload > 1100) ? XdrvMailbox.payload : HLW_IREF_PULSE; // HLW = 3500, CSE = 16140
|
||||
}
|
||||
nvalue = Settings.hlw_current_calibration;
|
||||
nvalue = Settings.energy_current_calibration;
|
||||
unit = UNIT_MICROSECOND;
|
||||
}
|
||||
else if ((ENERGY_HLW8012 == energy_flg) && (CMND_HLWISET == command_code)) {
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 16001) && hlw_cf1_current_pulse_length) {
|
||||
Settings.hlw_current_calibration = (XdrvMailbox.payload * hlw_cf1_current_pulse_length) / HLW_IREF;
|
||||
else if (((ENERGY_HLW8012 == energy_flg) || (ENERGY_CSE7766 == energy_flg)) && (CMND_CURRENTSET == command_code)) { // milliAmpere
|
||||
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 16001)) {
|
||||
if ((ENERGY_HLW8012 == energy_flg) && hlw_cf1_current_pulse_length) {
|
||||
Settings.energy_current_calibration = (XdrvMailbox.payload * hlw_cf1_current_pulse_length) / HLW_IREF;
|
||||
}
|
||||
else if ((ENERGY_CSE7766 == energy_flg) && current_cycle) {
|
||||
Settings.energy_current_calibration = (XdrvMailbox.payload * current_cycle) / 1000;
|
||||
}
|
||||
}
|
||||
snprintf_P(command, sizeof(command), PSTR(D_CMND_HLWICAL));
|
||||
nvalue = Settings.hlw_current_calibration;
|
||||
snprintf_P(command, sizeof(command), PSTR(D_CMND_CURRENTCAL));
|
||||
nvalue = Settings.energy_current_calibration;
|
||||
unit = UNIT_MICROSECOND;
|
||||
}
|
||||
|
||||
#if FEATURE_POWER_LIMIT
|
||||
else if (CMND_MAXPOWER == command_code) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) {
|
||||
@ -828,9 +965,9 @@ boolean EnergyCommand()
|
||||
}
|
||||
if (!status_flag) {
|
||||
if (Settings.flag.value_units) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames));
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, nvalue);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, nvalue);
|
||||
}
|
||||
}
|
||||
return serviced;
|
||||
@ -838,30 +975,42 @@ boolean EnergyCommand()
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void EnergyInit()
|
||||
void EnergyDrvInit()
|
||||
{
|
||||
energy_flg = ENERGY_NONE;
|
||||
if ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99)) {
|
||||
if ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99)) { // Sonoff Pow
|
||||
energy_flg = ENERGY_HLW8012;
|
||||
HlwInit();
|
||||
} else if (SONOFF_S31 == Settings.module) { // Sonoff S31
|
||||
baudrate = 4800;
|
||||
serial_config = SERIAL_8E1;
|
||||
energy_flg = ENERGY_CSE7766;
|
||||
#ifdef USE_PZEM004T
|
||||
} else if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX])) {
|
||||
if (PzemInit()) {
|
||||
energy_flg = ENERGY_PZEM004T;
|
||||
}
|
||||
} else if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX])) { // Any device with a Pzem004T
|
||||
energy_flg = ENERGY_PZEM004T;
|
||||
#endif // USE_PZEM004T
|
||||
}
|
||||
}
|
||||
|
||||
void EnergySnsInit()
|
||||
{
|
||||
if (ENERGY_HLW8012 == energy_flg) HlwInit();
|
||||
|
||||
#ifdef USE_PZEM004T
|
||||
if ((ENERGY_PZEM004T == energy_flg) && !PzemInit()) { // PzemInit needs to be done here as earlier (serial) interrupts may lead to Exceptions
|
||||
energy_flg = ENERGY_NONE;
|
||||
}
|
||||
#endif // USE_PZEM004T
|
||||
|
||||
if (energy_flg) {
|
||||
energy_kWhtoday = (RtcSettingsValid()) ? RtcSettings.energy_kWhtoday : 0;
|
||||
|
||||
energy_startup = 1;
|
||||
energy_kWhtoday = (RtcSettingsValid()) ? RtcSettings.energy_kWhtoday : (RtcTime.day_of_year == Settings.energy_kWhdoy) ? Settings.energy_kWhtoday : 0;
|
||||
energy_period = energy_kWhtoday;
|
||||
EnergyUpdateToday();
|
||||
ticker_energy.attach_ms(200, Energy200ms);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_SNS[] PROGMEM =
|
||||
const char HTTP_ENERGY_SNS[] PROGMEM = "%s"
|
||||
"{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
|
||||
"{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
|
||||
"{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"
|
||||
@ -887,9 +1036,7 @@ void EnergyShow(boolean json)
|
||||
|
||||
float energy = 0;
|
||||
if (show_energy_period) {
|
||||
if (energy_period) {
|
||||
energy = (float)(energy_kWhtoday - energy_period) / 100000;
|
||||
}
|
||||
if (energy_period) energy = (float)(energy_kWhtoday - energy_period) / 100000;
|
||||
energy_period = energy_kWhtoday;
|
||||
}
|
||||
|
||||
@ -916,7 +1063,7 @@ void EnergyShow(boolean json)
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS, energy_voltage_chr, energy_current_chr, energy_power_chr, energy_power_factor_chr, energy_daily_chr, energy_yesterday_chr, energy_total_chr);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS, mqtt_data, energy_voltage_chr, energy_current_chr, energy_power_chr, energy_power_factor_chr, energy_daily_chr, energy_yesterday_chr, energy_total_chr);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
@ -933,6 +1080,9 @@ boolean Xdrv03(byte function)
|
||||
|
||||
if (energy_flg) {
|
||||
switch (function) {
|
||||
case FUNC_INIT:
|
||||
EnergyDrvInit();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = EnergyCommand();
|
||||
break;
|
||||
@ -953,7 +1103,7 @@ boolean Xsns03(byte function)
|
||||
if (energy_flg) {
|
||||
switch (function) {
|
||||
case FUNC_INIT:
|
||||
EnergyInit();
|
||||
EnergySnsInit();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
EnergyMarginCheck();
|
||||
|
||||
@ -41,7 +41,7 @@ void SonoffBridgeLearnFailed()
|
||||
{
|
||||
sonoff_bridge_learn_active = 0;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARN_FAILED);
|
||||
MqttPublishPrefixTopic_P(5, PSTR(D_CMND_RFKEY));
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY));
|
||||
}
|
||||
|
||||
void SonoffBridgeReceived()
|
||||
@ -50,15 +50,9 @@ void SonoffBridgeReceived()
|
||||
uint16_t low_time = 0;
|
||||
uint16_t high_time = 0;
|
||||
uint32_t received_id = 0;
|
||||
char svalue[90];
|
||||
char rfkey[8];
|
||||
|
||||
svalue[0] = '\0';
|
||||
for (byte i = 0; i < serial_in_byte_counter; i++) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s%02X "), svalue, serial_in_buffer[i]);
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_BRIDGE D_RECEIVED " %s"), svalue);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
AddLogSerial(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (0xA2 == serial_in_buffer[0]) { // Learn timeout
|
||||
SonoffBridgeLearnFailed();
|
||||
@ -72,7 +66,7 @@ void SonoffBridgeReceived()
|
||||
Settings.rf_code[sonoff_bridge_learn_key][i] = serial_in_buffer[i +1];
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARNED);
|
||||
MqttPublishPrefixTopic_P(5, PSTR(D_CMND_RFKEY));
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY));
|
||||
} else {
|
||||
SonoffBridgeLearnFailed();
|
||||
}
|
||||
@ -102,7 +96,7 @@ void SonoffBridgeReceived()
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":\"%06X\",\"" D_CMND_RFKEY "\":%s}}"),
|
||||
sync_time, low_time, high_time, received_id, rfkey);
|
||||
MqttPublishPrefixTopic_P(6, PSTR(D_JSON_RFRECEIVED));
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED));
|
||||
#ifdef USE_DOMOTICZ
|
||||
DomoticzSensor(DZ_COUNT, received_id); // Send rid as Domoticz Counter value
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
@ -25,20 +25,18 @@ const char HTTP_FORM_DOMOTICZ[] PROGMEM =
|
||||
"<input id='w' name='w' value='4' hidden><input id='r' name='r' value='1' hidden>"
|
||||
"<br/><table>";
|
||||
const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM =
|
||||
"<tr><td width='260'><b>" D_DOMOTICZ_IDX " {1</b></td><td width='70'><input id='r{1' name='r{1' placeholder='0' value='{2'></td></tr>"
|
||||
"<tr><td width='260'><b>" D_DOMOTICZ_KEY_IDX " {1</b></td><td width='70'><input id='k{1' name='k{1' placeholder='0' value='{3'></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>";
|
||||
const char HTTP_FORM_DOMOTICZ_SWITCH[] PROGMEM =
|
||||
"<tr><td width='260'><b>" D_DOMOTICZ_SWITCH_IDX " {1</b></td><td width='70'><input id='s{1' name='s{1' placeholder='0' value='{4'></td></tr>";
|
||||
"<tr><td style='width:260px'><b>" D_DOMOTICZ_SWITCH_IDX " {1</b></td><td style='width:70px'><input id='s{1' name='s{1' placeholder='0' value='{4'></td></tr>";
|
||||
const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM =
|
||||
"<tr><td width='260'><b>" D_DOMOTICZ_SENSOR_IDX " {1</b> {2</td><td width='70'><input id='l{1' name='l{1' placeholder='0' value='{5'></td></tr>";
|
||||
"<tr><td style='width:260px'><b>" D_DOMOTICZ_SENSOR_IDX " {1</b> {2</td><td style='width:70px'><input id='l{1' name='l{1' placeholder='0' value='{5'></td></tr>";
|
||||
const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM =
|
||||
"<tr><td width='260'><b>" D_DOMOTICZ_UPDATE_TIMER "</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td width='70'><input id='ut' name='ut' placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>";
|
||||
"<tr><td style='width:260px'><b>" D_DOMOTICZ_UPDATE_TIMER "</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td style='width:70px'><input id='ut' name='ut' placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
enum DomoticzCommands {
|
||||
CMND_IDX, CMND_KEYIDX, CMND_SWITCHIDX, CMND_SENSORIDX, CMND_UPDATETIMER };
|
||||
const char kDomoticzCommands[] PROGMEM =
|
||||
D_CMND_IDX "|" D_CMND_KEYIDX "|" D_CMND_SWITCHIDX "|" D_CMND_SENSORIDX "|" D_CMND_UPDATETIMER ;
|
||||
enum DomoticzCommands { CMND_IDX, CMND_KEYIDX, CMND_SWITCHIDX, CMND_SENSORIDX, CMND_UPDATETIMER };
|
||||
const char kDomoticzCommands[] PROGMEM = D_CMND_IDX "|" D_CMND_KEYIDX "|" D_CMND_SWITCHIDX "|" D_CMND_SENSORIDX "|" D_CMND_UPDATETIMER ;
|
||||
|
||||
//enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_MAX_SENSORS};
|
||||
|
||||
@ -50,6 +48,7 @@ const char kDomoticzSensors[] PROGMEM =
|
||||
D_DOMOTICZ_TEMP "|" D_DOMOTICZ_TEMP_HUM "|" D_DOMOTICZ_TEMP_HUM_BARO "|" D_DOMOTICZ_POWER_ENERGY "|" D_DOMOTICZ_ILLUMINANCE "|" D_DOMOTICZ_COUNT "|" D_DOMOTICZ_VOLTAGE "|" D_DOMOTICZ_CURRENT "|" D_DOMOTICZ_AIRQUALITY ;
|
||||
|
||||
const char S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_DOMOTICZ "%s%d\":%d}";
|
||||
const char S_JSON_DOMOTICZ_COMMAND_INDEX_LVALUE[] PROGMEM = "{\"" D_CMND_DOMOTICZ "%s%d\":%lu}";
|
||||
|
||||
char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC;
|
||||
char domoticz_out_topic[] = DOMOTICZ_OUT_TOPIC;
|
||||
@ -94,11 +93,6 @@ void DomoticzMqttUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
void DomoticzSetUpdateTimer(uint16_t value)
|
||||
{
|
||||
domoticz_update_timer = value;
|
||||
}
|
||||
|
||||
void DomoticzMqttSubscribe()
|
||||
{
|
||||
uint8_t maxdev = (devices_present > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : devices_present;
|
||||
@ -134,7 +128,6 @@ void DomoticzMqttSubscribe()
|
||||
boolean DomoticzMqttData()
|
||||
{
|
||||
char stemp1[10];
|
||||
char scommand[10];
|
||||
unsigned long idx = 0;
|
||||
int16_t nvalue;
|
||||
int16_t found = 0;
|
||||
@ -172,7 +165,7 @@ boolean DomoticzMqttData()
|
||||
snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%d"), nvalue);
|
||||
found = 1;
|
||||
} else {
|
||||
if (((power >> i) &1) == nvalue) {
|
||||
if (((power >> i) &1) == (power_t)nvalue) {
|
||||
return 1;
|
||||
}
|
||||
snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_POWER "%s"), (devices_present > 1) ? stemp1 : "");
|
||||
@ -212,19 +205,19 @@ boolean DomoticzCommand()
|
||||
Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_relay_idx[XdrvMailbox.index -1]);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_LVALUE, command, XdrvMailbox.index, Settings.domoticz_relay_idx[XdrvMailbox.index -1]);
|
||||
}
|
||||
else if ((CMND_KEYIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
Settings.domoticz_key_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_key_idx[XdrvMailbox.index -1]);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_LVALUE, command, XdrvMailbox.index, Settings.domoticz_key_idx[XdrvMailbox.index -1]);
|
||||
}
|
||||
else if ((CMND_SWITCHIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
Settings.domoticz_switch_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_key_idx[XdrvMailbox.index -1]);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DOMOTICZ_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.domoticz_switch_idx[XdrvMailbox.index -1]);
|
||||
}
|
||||
else if ((CMND_SENSORIDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= DZ_MAX_SENSORS)) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
@ -339,10 +332,10 @@ void HandleDomoticzConfiguration()
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ);
|
||||
|
||||
char stemp[32];
|
||||
char *sensortype;
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_DOMOTICZ));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_DOMOTICZ);
|
||||
for (int i = 0; i < MAX_DOMOTICZ_IDX; i++) {
|
||||
if (i < devices_present) {
|
||||
@ -374,22 +367,28 @@ void DomoticzSaveSettings()
|
||||
{
|
||||
char stemp[20];
|
||||
char ssensor_indices[6 * MAX_DOMOTICZ_SNS_IDX];
|
||||
char tmp[100];
|
||||
|
||||
for (byte i = 0; i < MAX_DOMOTICZ_IDX; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("r%d"), i +1);
|
||||
Settings.domoticz_relay_idx[i] = (!strlen(WebServer->arg(stemp).c_str())) ? 0 : atoi(WebServer->arg(stemp).c_str());
|
||||
WebGetArg(stemp, tmp, sizeof(tmp));
|
||||
Settings.domoticz_relay_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("k%d"), i +1);
|
||||
Settings.domoticz_key_idx[i] = (!strlen(WebServer->arg(stemp).c_str())) ? 0 : atoi(WebServer->arg(stemp).c_str());
|
||||
WebGetArg(stemp, tmp, sizeof(tmp));
|
||||
Settings.domoticz_key_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("s%d"), i +1);
|
||||
Settings.domoticz_switch_idx[i] = (!strlen(WebServer->arg(stemp).c_str())) ? 0 : atoi(WebServer->arg(stemp).c_str());
|
||||
WebGetArg(stemp, tmp, sizeof(tmp));
|
||||
Settings.domoticz_switch_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
}
|
||||
ssensor_indices[0] = '\0';
|
||||
for (byte i = 0; i < DZ_MAX_SENSORS; i++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("l%d"), i +1);
|
||||
Settings.domoticz_sensor_idx[i] = (!strlen(WebServer->arg(stemp).c_str())) ? 0 : atoi(WebServer->arg(stemp).c_str());
|
||||
WebGetArg(stemp, tmp, sizeof(tmp));
|
||||
Settings.domoticz_sensor_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
snprintf_P(ssensor_indices, sizeof(ssensor_indices), PSTR("%s%s%d"), ssensor_indices, (strlen(ssensor_indices)) ? "," : "", Settings.domoticz_sensor_idx[i]);
|
||||
}
|
||||
Settings.domoticz_update_timer = (!strlen(WebServer->arg("ut").c_str())) ? DOMOTICZ_UPDATE_TIMER : atoi(WebServer->arg("ut").c_str());
|
||||
WebGetArg("ut", tmp, sizeof(tmp));
|
||||
Settings.domoticz_update_timer = (!strlen(tmp)) ? DOMOTICZ_UPDATE_TIMER : atoi(tmp);
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DOMOTICZ D_CMND_IDX " %d,%d,%d,%d, " D_CMND_KEYIDX " %d,%d,%d,%d, " D_CMND_SWITCHIDX " %d,%d,%d,%d, " D_CMND_SENSORIDX " %s, " D_CMND_UPDATETIMER " %d"),
|
||||
Settings.domoticz_relay_idx[0], Settings.domoticz_relay_idx[1], Settings.domoticz_relay_idx[2], Settings.domoticz_relay_idx[3],
|
||||
@ -398,6 +397,7 @@ void DomoticzSaveSettings()
|
||||
ssensor_indices, Settings.domoticz_update_timer);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
@ -417,6 +417,9 @@ boolean Xdrv05(byte function)
|
||||
case FUNC_MQTT_SUBSCRIBE:
|
||||
DomoticzMqttSubscribe();
|
||||
break;
|
||||
case FUNC_MQTT_INIT:
|
||||
domoticz_update_timer = 2;
|
||||
break;
|
||||
case FUNC_MQTT_DATA:
|
||||
result = DomoticzMqttData();
|
||||
break;
|
||||
@ -431,5 +434,4 @@ boolean Xdrv05(byte function)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_WEBSERVER
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
165
sonoff/xdrv_07_home_assistant.ino
Normal file
165
sonoff/xdrv_07_home_assistant.ino
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
xdrv_07_home_assistant.ino - home assistant support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
|
||||
const char HASS_DISCOVER_SWITCH[] PROGMEM =
|
||||
"{\"name\":\"%s\"," // dualr2 1
|
||||
"\"command_topic\":\"%s\"," // cmnd/dualr2/POWER2
|
||||
"\"state_topic\":\"%s\"," // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",")
|
||||
"\"value_template\":\"{{value_json.%s}}\"," // POWER2
|
||||
"\"payload_off\":\"%s\"," // OFF
|
||||
"\"payload_on\":\"%s\"," // ON
|
||||
// "\"optimistic\":\"false\"," // false is Hass default when state_topic is set
|
||||
"\"availability_topic\":\"%s\"," // tele/dualr2/LWT
|
||||
"\"payload_available\":\"" D_ONLINE "\"," // Online
|
||||
"\"payload_not_available\":\"" D_OFFLINE "\""; // Offline
|
||||
|
||||
const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM =
|
||||
"%s,\"brightness_command_topic\":\"%s\"," // cmnd/led2/Dimmer
|
||||
"\"brightness_state_topic\":\"%s\"," // stat/led2/RESULT
|
||||
"\"brightness_scale\":100," // 100%
|
||||
"\"on_command_type\":\"brightness\"," // power on (first), power on (last), no power on (brightness)
|
||||
"\"brightness_value_template\":\"{{value_json." D_CMND_DIMMER "}}\"";
|
||||
|
||||
const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM =
|
||||
"%s,\"rgb_command_topic\":\"%s\"," // cmnd/led2/Color
|
||||
"\"rgb_state_topic\":\"%s\"," // stat/led2/RESULT
|
||||
"\"rgb_value_template\":\"{{value_json." D_CMND_COLOR "}}\"";
|
||||
// "\"rgb_value_template\":\"{{value_json." D_CMND_COLOR " | join(',')}}\"";
|
||||
|
||||
const char HASS_DISCOVER_LIGHT_CT[] PROGMEM =
|
||||
"%s,\"color_temp_command_topic\":\"%s\"," // cmnd/led2/CT
|
||||
"\"color_temp_state_topic\":\"%s\"," // stat/led2/RESULT
|
||||
"\"color_temp_value_template\":\"{{value_json." D_CMND_COLORTEMPERATURE "}}\"";
|
||||
/*
|
||||
const char HASS_DISCOVER_LIGHT_SCHEME[] PROGMEM =
|
||||
"%s,\"effect_command_topic\":\"%s\"," // cmnd/led2/Scheme
|
||||
"\"effect_state_topic\":\"%s\"," // stat/led2/RESULT
|
||||
"\"effect_value_template\":\"{{value_json." D_CMND_SCHEME "}}\","
|
||||
"\"effect_list\":\"[0, 1, 2, 3, 4]\""; // Needs to be a Python string list providing Scheme parameter values (Unable to get this functional)
|
||||
*/
|
||||
/*
|
||||
#1690 - investigate
|
||||
effect_list:
|
||||
- 0
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
- 7
|
||||
- 8
|
||||
- 9
|
||||
- 10
|
||||
- 11
|
||||
- 12
|
||||
*/
|
||||
void HAssDiscovery()
|
||||
{
|
||||
char sidx[8];
|
||||
char stopic[TOPSZ];
|
||||
bool is_light = false;
|
||||
|
||||
// Configure Tasmota for default Home Assistant parameters to keep discovery message as short as possible
|
||||
if (Settings.flag.hass_discovery) {
|
||||
Settings.flag.mqtt_response = 0; // Response always as RESULT and not as uppercase command
|
||||
Settings.flag.decimal_text = 1; // Respond with decimal color values
|
||||
// Settings.light_scheme = 0; // To just control color it needs to be Scheme 0
|
||||
// strncpy_P(Settings.mqtt_fulltopic, PSTR("%prefix%/%topic%/"), sizeof(Settings.mqtt_fulltopic)); // Make MQTT topic as short as possible to make this process posible within MQTT_MAX_PACKET_SIZE
|
||||
}
|
||||
|
||||
for (int i = 1; i <= devices_present; i++) {
|
||||
is_light = ((i == devices_present) && (light_type));
|
||||
|
||||
snprintf_P(sidx, sizeof(sidx), PSTR("_%d"), i);
|
||||
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), (is_light) ? "light" : "switch", Settings.mqtt_topic, (1 == devices_present) ? "" : sidx);
|
||||
|
||||
mqtt_data[0] = '\0';
|
||||
if (Settings.flag.hass_discovery) {
|
||||
char name[33];
|
||||
char value_template[33];
|
||||
char command_topic[TOPSZ];
|
||||
char state_topic[TOPSZ];
|
||||
char availability_topic[TOPSZ];
|
||||
|
||||
if (i > MAX_FRIENDLYNAMES) {
|
||||
snprintf_P(name, sizeof(name), PSTR("%s %d"), Settings.friendlyname[0], i);
|
||||
} else {
|
||||
snprintf_P(name, sizeof(name), Settings.friendlyname[i -1]);
|
||||
}
|
||||
GetPowerDevice(value_template, i, sizeof(value_template));
|
||||
GetTopic_P(command_topic, CMND, Settings.mqtt_topic, value_template);
|
||||
GetTopic_P(state_topic, STAT, Settings.mqtt_topic, S_RSLT_RESULT);
|
||||
GetTopic_P(availability_topic, TELE, Settings.mqtt_topic, S_LWT);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SWITCH, name, command_topic, state_topic, value_template, Settings.state_text[0], Settings.state_text[1], availability_topic);
|
||||
|
||||
if (is_light) {
|
||||
char brightness_command_topic[TOPSZ];
|
||||
|
||||
GetTopic_P(brightness_command_topic, CMND, Settings.mqtt_topic, D_CMND_DIMMER);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_DIMMER, mqtt_data, brightness_command_topic, state_topic);
|
||||
|
||||
if (light_subtype >= LST_RGB) {
|
||||
char rgb_command_topic[TOPSZ];
|
||||
|
||||
GetTopic_P(rgb_command_topic, CMND, Settings.mqtt_topic, D_CMND_COLOR);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_COLOR, mqtt_data, rgb_command_topic, state_topic);
|
||||
/*
|
||||
char effect_command_topic[TOPSZ];
|
||||
|
||||
GetTopic_P(effect_command_topic, CMND, Settings.mqtt_topic, D_CMND_SCHEME);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_SCHEME, mqtt_data, effect_command_topic, state_topic);
|
||||
*/
|
||||
}
|
||||
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
||||
char color_temp_command_topic[TOPSZ];
|
||||
|
||||
GetTopic_P(color_temp_command_topic, CMND, Settings.mqtt_topic, D_CMND_COLORTEMPERATURE);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_CT, mqtt_data, color_temp_command_topic, state_topic);
|
||||
}
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
}
|
||||
MqttPublish(stopic, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_07
|
||||
|
||||
boolean Xdrv07(byte function)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (Settings.flag.mqtt_enabled) {
|
||||
switch (function) {
|
||||
case FUNC_MQTT_INIT:
|
||||
HAssDiscovery();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_HOME_ASSISTANT
|
||||
@ -17,58 +17,127 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void XDrvInit()
|
||||
{
|
||||
for (byte i = 0; i < XDRV_MAX; i++) {
|
||||
xdrv_func_ptr[i] = NULL;
|
||||
}
|
||||
xdrv_present = 0;
|
||||
|
||||
boolean (* const xdrv_func_ptr[])(byte) PROGMEM = { // Driver Function Pointers
|
||||
#ifdef XDRV_01
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv01;
|
||||
&Xdrv01,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_02
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv02;
|
||||
&Xdrv02,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_03
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv03;
|
||||
&Xdrv03,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_04
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv04;
|
||||
&Xdrv04,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_05
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv05;
|
||||
&Xdrv05,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_06
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv06;
|
||||
&Xdrv06,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_07
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv07;
|
||||
&Xdrv07,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_08
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv08;
|
||||
&Xdrv08,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_09
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv09;
|
||||
&Xdrv09,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_10
|
||||
xdrv_func_ptr[xdrv_present++] = &Xdrv10;
|
||||
&Xdrv10,
|
||||
#endif
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "Drivers %d"), xdrv_present);
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
#ifdef XDRV_11
|
||||
&Xdrv11,
|
||||
#endif
|
||||
|
||||
XdrvCall(FUNC_INIT);
|
||||
}
|
||||
#ifdef XDRV_12
|
||||
&Xdrv12,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_13
|
||||
&Xdrv13,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_14
|
||||
&Xdrv14,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_15
|
||||
&Xdrv15,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_16
|
||||
&Xdrv16,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_17
|
||||
&Xdrv17,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_18
|
||||
&Xdrv18,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_19
|
||||
&Xdrv19,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_20
|
||||
&Xdrv20,
|
||||
#endif
|
||||
|
||||
// Optional user defined drivers in range 91 - 99
|
||||
|
||||
#ifdef XDRV_91
|
||||
&Xdrv91,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_92
|
||||
&Xdrv92,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_93
|
||||
&Xdrv93,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_94
|
||||
&Xdrv94,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_95
|
||||
&Xdrv95,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_96
|
||||
&Xdrv96,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_97
|
||||
&Xdrv97,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_98
|
||||
&Xdrv98,
|
||||
#endif
|
||||
|
||||
#ifdef XDRV_99
|
||||
&Xdrv99
|
||||
#endif
|
||||
};
|
||||
|
||||
const uint8_t xdrv_present = sizeof(xdrv_func_ptr) / sizeof(xdrv_func_ptr[0]); // Number of drivers found
|
||||
|
||||
boolean XdrvCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload)
|
||||
{
|
||||
@ -82,7 +151,7 @@ boolean XdrvCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_len
|
||||
return XdrvCall(FUNC_COMMAND);
|
||||
}
|
||||
|
||||
void XdrvSetPower(uint8_t mpower)
|
||||
void XdrvSetPower(power_t mpower)
|
||||
{
|
||||
// XdrvMailbox.valid = 1;
|
||||
XdrvMailbox.index = mpower;
|
||||
@ -102,6 +171,16 @@ boolean XdrvMqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uint16_t
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Function call to all xdrv
|
||||
*
|
||||
* FUNC_INIT
|
||||
* FUNC_MQTT_SUBSCRIBE
|
||||
* FUNC_MQTT_INIT
|
||||
* return FUNC_MQTT_DATA
|
||||
* return FUNC_COMMAND
|
||||
* FUNC_SET_POWER
|
||||
* FUNC_SHOW_SENSOR
|
||||
* FUNC_EVERY_SECOND
|
||||
* FUNC_EVERY_50_MSECOND
|
||||
\*********************************************************************************************/
|
||||
|
||||
boolean XdrvCall(byte Function)
|
||||
|
||||
@ -388,10 +388,10 @@ void HandleUpnpEvent()
|
||||
//differentiate get and set state
|
||||
if (request.indexOf(F("SetBinaryState")) > 0) {
|
||||
if (request.indexOf(F("State>1</Binary")) > 0) {
|
||||
ExecuteCommandPower(devices_present, 1);
|
||||
ExecuteCommandPower(devices_present, POWER_ON);
|
||||
}
|
||||
else if (request.indexOf(F("State>0</Binary")) > 0) {
|
||||
ExecuteCommandPower(devices_present, 0);
|
||||
ExecuteCommandPower(devices_present, POWER_OFF);
|
||||
}
|
||||
}
|
||||
else if(request.indexOf(F("GetBinaryState")) > 0){
|
||||
@ -452,8 +452,8 @@ const char HUE_DESCRIPTION_XML[] PROGMEM =
|
||||
"</device>"
|
||||
"</root>\r\n"
|
||||
"\r\n";
|
||||
const char HueLightStatus_JSON[] PROGMEM =
|
||||
"\"on\":{state},"
|
||||
const char HUE_LIGHTS_STATUS_JSON[] PROGMEM =
|
||||
"{\"on\":{state},"
|
||||
"\"bri\":{b},"
|
||||
"\"hue\":{h},"
|
||||
"\"sat\":{s},"
|
||||
@ -462,19 +462,18 @@ const char HueLightStatus_JSON[] PROGMEM =
|
||||
"\"alert\":\"none\","
|
||||
"\"effect\":\"none\","
|
||||
"\"colormode\":\"hs\","
|
||||
"\"reachable\":true";
|
||||
const char HUE_LIGHTS_STATUS_JSON[] PROGMEM =
|
||||
"\"type\":\"Extended color light\","
|
||||
"\"reachable\":true}";
|
||||
const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM =
|
||||
",\"type\":\"Extended color light\","
|
||||
"\"name\":\"{j1\","
|
||||
"\"modelid\":\"LCT007\","
|
||||
"\"uniqueid\":\"{j2\","
|
||||
"\"swversion\":\"5.50.1.19085\""
|
||||
"}";
|
||||
"\"swversion\":\"5.50.1.19085\"}";
|
||||
const char HUE_GROUP0_STATUS_JSON[] PROGMEM =
|
||||
"{\"name\":\"Group 0\","
|
||||
"\"lights\":[{l1],"
|
||||
"\"type\":\"LightGroup\","
|
||||
"\"action\":{";
|
||||
"\"action\":";
|
||||
// "\"scene\":\"none\",";
|
||||
const char HueConfigResponse_JSON[] PROGMEM =
|
||||
"{\"name\":\"Philips hue\","
|
||||
@ -556,18 +555,27 @@ void HueConfig(String *path)
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
|
||||
}
|
||||
|
||||
void HueLightStatus(byte device, String *response)
|
||||
void HueLightStatus1(byte device, String *response)
|
||||
{
|
||||
*response += FPSTR(HueLightStatus_JSON);
|
||||
response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false");
|
||||
float hue = 0;
|
||||
float sat = 0;
|
||||
float bri = 0;
|
||||
|
||||
if (light_type) {
|
||||
LightReplaceHsb(response);
|
||||
} else {
|
||||
response->replace("{h}", "0");
|
||||
response->replace("{s}", "0");
|
||||
response->replace("{b}", "0");
|
||||
LightGetHsb(&hue, &sat, &bri);
|
||||
}
|
||||
*response += FPSTR(HUE_LIGHTS_STATUS_JSON);
|
||||
response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false");
|
||||
response->replace("{h}", String((uint16_t)(65535.0f * hue)));
|
||||
response->replace("{s}", String((uint8_t)(254.0f * sat)));
|
||||
response->replace("{b}", String((uint8_t)(254.0f * bri)));
|
||||
}
|
||||
|
||||
void HueLightStatus2(byte device, String *response)
|
||||
{
|
||||
*response += FPSTR(HUE_LIGHTS_STATUS_JSON2);
|
||||
response->replace("{j1", Settings.friendlyname[device-1]);
|
||||
response->replace("{j2", GetHueDeviceId(device));
|
||||
}
|
||||
|
||||
void HueGlobalConfig(String *path)
|
||||
@ -579,12 +587,9 @@ void HueGlobalConfig(String *path)
|
||||
response = F("{\"lights\":{\"");
|
||||
for (uint8_t i = 1; i <= maxhue; i++) {
|
||||
response += i;
|
||||
response += F("\":{\"state\":{");
|
||||
HueLightStatus(i, &response);
|
||||
response += "},";
|
||||
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
|
||||
response.replace("{j1", Settings.friendlyname[i-1]);
|
||||
response.replace("{j2", GetHueDeviceId(i));
|
||||
response += F("\":{\"state\":");
|
||||
HueLightStatus1(i, &response);
|
||||
HueLightStatus2(i, &response);
|
||||
if (i < maxhue) {
|
||||
response += ",\"";
|
||||
}
|
||||
@ -611,7 +616,6 @@ void HueLights(String *path)
|
||||
String response;
|
||||
uint8_t device = 1;
|
||||
uint16_t tmp = 0;
|
||||
int16_t pos = 0;
|
||||
float bri = 0;
|
||||
float hue = 0;
|
||||
float sat = 0;
|
||||
@ -619,7 +623,6 @@ void HueLights(String *path)
|
||||
bool resp = false;
|
||||
bool on = false;
|
||||
bool change = false;
|
||||
char id[4];
|
||||
uint8_t maxhue = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present;
|
||||
|
||||
path->remove(0,path->indexOf("/lights")); // Remove until /lights
|
||||
@ -627,12 +630,9 @@ void HueLights(String *path)
|
||||
response = "{\"";
|
||||
for (uint8_t i = 1; i <= maxhue; i++) {
|
||||
response += i;
|
||||
response += F("\":{\"state\":{");
|
||||
HueLightStatus(i, &response);
|
||||
response += "},";
|
||||
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
|
||||
response.replace("{j1", Settings.friendlyname[i-1]);
|
||||
response.replace("{j2", GetHueDeviceId(i));
|
||||
response += F("\":{\"state\":");
|
||||
HueLightStatus1(i, &response);
|
||||
HueLightStatus2(i, &response);
|
||||
if (i < maxhue) {
|
||||
response += ",\"";
|
||||
}
|
||||
@ -661,10 +661,10 @@ void HueLights(String *path)
|
||||
on = hue_json["on"];
|
||||
switch(on)
|
||||
{
|
||||
case false : ExecuteCommandPower(device, 0);
|
||||
case false : ExecuteCommandPower(device, POWER_OFF);
|
||||
response.replace("{re", "false");
|
||||
break;
|
||||
case true : ExecuteCommandPower(device, 1);
|
||||
case true : ExecuteCommandPower(device, POWER_ON);
|
||||
response.replace("{re", "true");
|
||||
break;
|
||||
default : response.replace("{re", (power & (1 << (device-1))) ? "true" : "false");
|
||||
@ -674,7 +674,7 @@ void HueLights(String *path)
|
||||
}
|
||||
|
||||
if (light_type) {
|
||||
LightGetHsb(&hue,&sat,&bri);
|
||||
LightGetHsb(&hue, &sat, &bri);
|
||||
}
|
||||
|
||||
if (hue_json.containsKey("bri")) {
|
||||
@ -749,12 +749,9 @@ void HueLights(String *path)
|
||||
if ((device < 1) || (device > maxhue)) {
|
||||
device = 1;
|
||||
}
|
||||
response += F("{\"state\":{");
|
||||
HueLightStatus(device, &response);
|
||||
response += "},";
|
||||
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
|
||||
response.replace("{j1", Settings.friendlyname[device-1]);
|
||||
response.replace("{j2", GetHueDeviceId(device));
|
||||
response += F("{\"state\":");
|
||||
HueLightStatus1(device, &response);
|
||||
HueLightStatus2(device, &response);
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
|
||||
}
|
||||
else {
|
||||
@ -777,8 +774,8 @@ void HueGroups(String *path)
|
||||
lights += ",\"" + String(i) + "\"";
|
||||
}
|
||||
response.replace("{l1", lights);
|
||||
HueLightStatus(1, &response);
|
||||
response += F("}}");
|
||||
HueLightStatus1(1, &response);
|
||||
response += F("}");
|
||||
}
|
||||
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
|
||||
|
||||
@ -105,7 +105,7 @@ void SonoffScSerialInput(char *rcvstat)
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_SCPLUS[] PROGMEM =
|
||||
"%s{s}" D_LIGHT "{m}%d%{e}{s}" D_NOISE "{m}%d%{e}{s}" D_AIR_QUALITY "{m}%d%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
"%s{s}" D_LIGHT "{m}%d%%{e}{s}" D_NOISE "{m}%d%%{e}{s}" D_AIR_QUALITY "{m}%d%%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void SonoffScShow(boolean json)
|
||||
|
||||
@ -192,7 +192,7 @@ void Ds18b20Show(boolean json)
|
||||
if (Ds18b20Read(t)) { // Check if read failed
|
||||
char temperature[10];
|
||||
|
||||
dtostrfi(t, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
|
||||
if(json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"DS18B20\":{\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, temperature);
|
||||
|
||||
@ -404,8 +404,13 @@ boolean Xsns05(byte function)
|
||||
case FUNC_INIT:
|
||||
Ds18x20Init();
|
||||
break;
|
||||
// case FUNC_EVERY_SECOND:
|
||||
// if ((Settings.tele_period - tele_period) &3 == 3) {
|
||||
// Ds18x20Convert(); // Start conversion every four seconds, takes up to one second
|
||||
// }
|
||||
// break;
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Ds18x20Show(1);
|
||||
@ -413,7 +418,7 @@ boolean Xsns05(byte function)
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_APPEND:
|
||||
Ds18x20Show(0);
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
|
||||
@ -40,8 +40,8 @@ struct DHTSTRUCT {
|
||||
char stype[12];
|
||||
uint32_t lastreadtime;
|
||||
uint8_t lastresult;
|
||||
float t;
|
||||
float h = 0;
|
||||
float t = NAN;
|
||||
float h = NAN;
|
||||
} Dht[DHT_MAX_SENSORS];
|
||||
|
||||
void DhtReadPrep()
|
||||
@ -56,7 +56,7 @@ int32_t DhtExpectPulse(byte sensor, bool level)
|
||||
int32_t count = 0;
|
||||
|
||||
while (digitalRead(Dht[sensor].pin) == level) {
|
||||
if (count++ >= dht_max_cycles) {
|
||||
if (count++ >= (int32_t)dht_max_cycles) {
|
||||
return -1; // Timeout
|
||||
}
|
||||
}
|
||||
@ -141,7 +141,7 @@ void DhtRead(byte sensor)
|
||||
|
||||
boolean DhtReadTempHum(byte sensor, float &t, float &h)
|
||||
{
|
||||
if (!Dht[sensor].h) {
|
||||
if (NAN == Dht[sensor].h) {
|
||||
t = NAN;
|
||||
h = NAN;
|
||||
} else {
|
||||
@ -203,7 +203,7 @@ void DhtInit()
|
||||
pinMode(Dht[i].pin, INPUT_PULLUP);
|
||||
Dht[i].lastreadtime = 0;
|
||||
Dht[i].lastresult = 0;
|
||||
strcpy_P(Dht[i].stype, kSensors[Dht[i].type]);
|
||||
GetTextIndexed(Dht[i].stype, sizeof(Dht[i].stype), Dht[i].type, kSensorNames);
|
||||
if (dht_sensors > 1) {
|
||||
snprintf_P(Dht[i].stype, sizeof(Dht[i].stype), PSTR("%s-%02d"), Dht[i].stype, Dht[i].pin);
|
||||
}
|
||||
@ -214,11 +214,11 @@ void DhtShow(boolean json)
|
||||
{
|
||||
char temperature[10];
|
||||
char humidity[10];
|
||||
float t;
|
||||
float h;
|
||||
|
||||
byte dsxflg = 0;
|
||||
for (byte i = 0; i < dht_sensors; i++) {
|
||||
float t = NAN;
|
||||
float h = NAN;
|
||||
if (DhtReadTempHum(i, t, h)) { // Read temperature
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
||||
|
||||
@ -206,6 +206,7 @@ float HtuCompensatedHumidity(float humidity, float temperature)
|
||||
if(temperature > 0.00 && temperature < 80.00) {
|
||||
return (-0.15)*(25-temperature)+humidity;
|
||||
}
|
||||
return humidity;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
@ -98,16 +98,16 @@ boolean Bmp180Calibration()
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((cal_ac1 == 0xFFFF) |
|
||||
(cal_ac2 == 0xFFFF) |
|
||||
(cal_ac3 == 0xFFFF) |
|
||||
if ((cal_ac1 == (int16_t)0xFFFF) |
|
||||
(cal_ac2 == (int16_t)0xFFFF) |
|
||||
(cal_ac3 == (int16_t)0xFFFF) |
|
||||
(cal_ac4 == 0xFFFF) |
|
||||
(cal_ac5 == 0xFFFF) |
|
||||
(cal_ac6 == 0xFFFF) |
|
||||
(cal_b1 == 0xFFFF) |
|
||||
(cal_b2 == 0xFFFF) |
|
||||
(cal_mc == 0xFFFF) |
|
||||
(cal_md == 0xFFFF)) {
|
||||
(cal_b1 == (int16_t)0xFFFF) |
|
||||
(cal_b2 == (int16_t)0xFFFF) |
|
||||
(cal_mc == (int16_t)0xFFFF) |
|
||||
(cal_md == (int16_t)0xFFFF)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -128,9 +128,6 @@ double Bmp180ReadTemperature()
|
||||
double Bmp180ReadPressure()
|
||||
{
|
||||
int32_t p;
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
uint8_t xlsb;
|
||||
|
||||
I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution
|
||||
delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution
|
||||
@ -504,8 +501,14 @@ boolean Xsns09(byte function)
|
||||
switch (function) {
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
BmpDetect();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
#ifdef USE_BME680
|
||||
Bme680PerformReading();
|
||||
if ((Settings.tele_period - tele_period) < 300) { // 5 minute stabilization time
|
||||
if (tele_period &1) {
|
||||
Bme680PerformReading(); // Keep BME680 busy every two seconds
|
||||
}
|
||||
}
|
||||
#endif // USE_BME680
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
|
||||
@ -19,6 +19,9 @@
|
||||
|
||||
#ifdef USE_I2C
|
||||
#ifdef USE_INA219
|
||||
|
||||
#define XSNS_13 13
|
||||
|
||||
/*********************************************************************************************\
|
||||
* INA219 - Low voltage (max 32V!) Current sensor
|
||||
*
|
||||
@ -152,6 +155,23 @@ float Ina219GetCurrent_mA()
|
||||
return value;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Command Sensor13
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Ina219CommandSensor()
|
||||
{
|
||||
boolean serviced = true;
|
||||
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) {
|
||||
Settings.ina219_mode = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_NVALUE, XSNS_13, Settings.ina219_mode);
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Ina219Detect()
|
||||
@ -211,14 +231,17 @@ void Ina219Show(boolean json)
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_13
|
||||
|
||||
boolean Xsns13(byte function)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (i2c_flg) {
|
||||
switch (function) {
|
||||
case FUNC_COMMAND:
|
||||
if ((XSNS_13 == XdrvMailbox.index) && (ina219_type)) {
|
||||
result = Ina219CommandSensor();
|
||||
}
|
||||
break;
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
Ina219Detect();
|
||||
break;
|
||||
|
||||
@ -18,6 +18,9 @@
|
||||
*/
|
||||
|
||||
#ifdef USE_MHZ19
|
||||
|
||||
#define XSNS_15 15
|
||||
|
||||
/*********************************************************************************************\
|
||||
* MH-Z19 - CO2 sensor
|
||||
*
|
||||
@ -71,6 +74,7 @@ const char kMhzTypes[] PROGMEM = "MHZ19|MHZ19B";
|
||||
const uint8_t mhz_cmnd_read_ppm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
|
||||
const uint8_t mhz_cmnd_abc_enable[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6};
|
||||
const uint8_t mhz_cmnd_abc_disable[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86};
|
||||
const uint8_t mhz_cmnd_zeropoint[9] = {0xff, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78};
|
||||
|
||||
uint8_t mhz_type = 1;
|
||||
uint16_t mhz_last_ppm = 0;
|
||||
@ -134,6 +138,7 @@ void Mhz50ms()
|
||||
if (6 == mhz_timer) { // MH-Z19 measuring cycle takes 1005 +5% ms
|
||||
mhz_timer = 0;
|
||||
|
||||
MhzSerial->flush();
|
||||
MhzSerial->write(mhz_cmnd_read_ppm, 9);
|
||||
}
|
||||
|
||||
@ -207,6 +212,34 @@ void Mhz50ms()
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Command Sensor15
|
||||
\*********************************************************************************************/
|
||||
|
||||
/*
|
||||
0 - ABC Off
|
||||
1 - ABC On
|
||||
2 - Manual start = ABC Off
|
||||
|
||||
3 - Optional filter settings
|
||||
*/
|
||||
|
||||
bool MhzCommandSensor()
|
||||
{
|
||||
boolean serviced = true;
|
||||
|
||||
switch (XdrvMailbox.payload) {
|
||||
case 2:
|
||||
MhzSerial->write(mhz_cmnd_zeropoint, 9);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION);
|
||||
break;
|
||||
default:
|
||||
serviced = false;
|
||||
}
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void MhzInit()
|
||||
@ -243,8 +276,6 @@ void MhzShow(boolean json)
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_15
|
||||
|
||||
boolean Xsns15(byte function)
|
||||
{
|
||||
boolean result = false;
|
||||
@ -257,6 +288,11 @@ boolean Xsns15(byte function)
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
Mhz50ms();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
if (XSNS_15 == XdrvMailbox.index) {
|
||||
result = MhzCommandSensor();
|
||||
}
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
MhzShow(1);
|
||||
break;
|
||||
|
||||
@ -31,27 +31,30 @@
|
||||
|
||||
uint8_t tsl2561_address;
|
||||
uint8_t tsl2561_addresses[] = { TSL2561_ADDR_LOW, TSL2561_ADDR_FLOAT, TSL2561_ADDR_HIGH };
|
||||
uint8_t tsl2561_type = 0;
|
||||
|
||||
//TSL2561 tsl(TSL2561_ADDR_FLOAT);
|
||||
TSL2561 *tsl;
|
||||
TSL2561 *tsl = 0;
|
||||
|
||||
void Tsl2561Detect()
|
||||
{
|
||||
if (tsl2561_type) {
|
||||
if (tsl) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (byte i = 0; i < sizeof(tsl2561_addresses); i++) {
|
||||
tsl2561_address = tsl2561_addresses[i];
|
||||
tsl = new TSL2561(tsl2561_address);
|
||||
if (tsl->begin()) {
|
||||
tsl->setGain(TSL2561_GAIN_16X);
|
||||
tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS);
|
||||
tsl2561_type = 1;
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "TSL2561", tsl2561_address);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
break;
|
||||
if (I2cDevice(tsl2561_address)) {
|
||||
tsl = new TSL2561(tsl2561_address);
|
||||
if (tsl->begin()) {
|
||||
tsl->setGain(TSL2561_GAIN_16X);
|
||||
tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS);
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "TSL2561", tsl2561_address);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
break;
|
||||
} else {
|
||||
delete tsl;
|
||||
tsl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,8 +66,23 @@ const char HTTP_SNS_TSL2561[] PROGMEM =
|
||||
|
||||
void Tsl2561Show(boolean json)
|
||||
{
|
||||
if (tsl2561_type) {
|
||||
uint16_t illuminance = tsl->getLuminosity(TSL2561_VISIBLE);
|
||||
if (tsl) {
|
||||
union {
|
||||
uint32_t full;
|
||||
struct { uint16_t both, ir; };
|
||||
} light;
|
||||
light.full = tsl->getFullLuminosity();
|
||||
uint32_t illuminance = 0;
|
||||
if ((light.full == 0 || light.full == 0xffffffff)) {
|
||||
if (!I2cDevice(tsl2561_address)) {
|
||||
delete tsl;
|
||||
tsl = 0;
|
||||
}
|
||||
} else {
|
||||
illuminance = tsl->calculateLux(light.both, light.ir);
|
||||
}
|
||||
snprintf(log_data, sizeof(log_data), PSTR(D_ILLUMINANCE " 0x%08lx = b 0x%04x, i 0x%04x -> %lu " D_UNIT_LUX), light.full, light.both, light.ir, illuminance);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"TSL2561\":{\"" D_JSON_ILLUMINANCE "\":%d}"), mqtt_data, illuminance);
|
||||
@ -108,4 +126,4 @@ boolean Xsns16(byte function)
|
||||
}
|
||||
|
||||
#endif // USE_TSL2561
|
||||
#endif // USE_I2C
|
||||
#endif // USE_I2C
|
||||
@ -74,6 +74,7 @@ void ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register
|
||||
frame[7] = (uint8_t)((crc >> 8) & 0xFF);
|
||||
frame[6] = (uint8_t)(crc & 0xFF);
|
||||
|
||||
SensairSerial->flush();
|
||||
SensairSerial->write(frame, sizeof(frame));
|
||||
}
|
||||
|
||||
|
||||
173
sonoff/xsns_18_pms5003.ino
Normal file
173
sonoff/xsns_18_pms5003.ino
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
xsns_18_pms5003.ino - PMS5003-7003 particle concentration sensor support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_PMS5003
|
||||
/*********************************************************************************************\
|
||||
* PlanTower PMS5003 and PMS7003 particle concentration sensor
|
||||
* For background information see http://aqicn.org/sensor/pms5003-7003/
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
TasmotaSerial *PmsSerial;
|
||||
|
||||
uint8_t pms_type = 1;
|
||||
uint8_t pms_valid = 0;
|
||||
|
||||
struct pms5003data {
|
||||
uint16_t framelen;
|
||||
uint16_t pm10_standard, pm25_standard, pm100_standard;
|
||||
uint16_t pm10_env, pm25_env, pm100_env;
|
||||
uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
|
||||
uint16_t unused;
|
||||
uint16_t checksum;
|
||||
} pms_data;
|
||||
|
||||
boolean PmsReadData()
|
||||
{
|
||||
if (! PmsSerial->available()) {
|
||||
return false;
|
||||
}
|
||||
while ((PmsSerial->peek() != 0x42) && PmsSerial->available()) {
|
||||
PmsSerial->read();
|
||||
}
|
||||
if (PmsSerial->available() < 32) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t buffer[32];
|
||||
uint16_t sum = 0;
|
||||
PmsSerial->readBytes(buffer, 32);
|
||||
PmsSerial->flush(); // Make room for another burst
|
||||
|
||||
// get checksum ready
|
||||
for (uint8_t i = 0; i < 30; i++) {
|
||||
sum += buffer[i];
|
||||
}
|
||||
// The data comes in endian'd, this solves it so it works on all platforms
|
||||
uint16_t buffer_u16[15];
|
||||
for (uint8_t i = 0; i < 15; i++) {
|
||||
buffer_u16[i] = buffer[2 + i*2 + 1];
|
||||
buffer_u16[i] += (buffer[2 + i*2] << 8);
|
||||
}
|
||||
if (sum != buffer_u16[14]) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("PMS: " D_CHECKSUM_FAILURE));
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy((void *)&pms_data, (void *)buffer_u16, 30);
|
||||
pms_valid = 10;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void PmsSecond() // Every second
|
||||
{
|
||||
if (PmsReadData()) {
|
||||
pms_valid = 10;
|
||||
} else {
|
||||
if (pms_valid) {
|
||||
pms_valid--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void PmsInit()
|
||||
{
|
||||
pms_type = 0;
|
||||
|
||||
if (pin[GPIO_PMS5003] < 99) {
|
||||
PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003], -1);
|
||||
if (PmsSerial->begin()) {
|
||||
pms_type = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_PMS5003_SNS[] PROGMEM = "%s"
|
||||
// "{s}PMS5003 " D_STANDARD_CONCENTRATION " 1 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"
|
||||
// "{s}PMS5003 " D_STANDARD_CONCENTRATION " 2.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"
|
||||
// "{s}PMS5003 " D_STANDARD_CONCENTRATION " 10 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"
|
||||
"{s}PMS5003 " D_ENVIRONMENTAL_CONCENTRATION " 1 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"
|
||||
"{s}PMS5003 " D_ENVIRONMENTAL_CONCENTRATION " 2.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"
|
||||
"{s}PMS5003 " D_ENVIRONMENTAL_CONCENTRATION " 10 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"
|
||||
"{s}PMS5003 " D_PARTICALS_BEYOND " 0.3 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
|
||||
"{s}PMS5003 " D_PARTICALS_BEYOND " 0.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
|
||||
"{s}PMS5003 " D_PARTICALS_BEYOND " 1 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
|
||||
"{s}PMS5003 " D_PARTICALS_BEYOND " 2.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
|
||||
"{s}PMS5003 " D_PARTICALS_BEYOND " 5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
|
||||
"{s}PMS5003 " D_PARTICALS_BEYOND " 10 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void PmsShow(boolean json)
|
||||
{
|
||||
if (pms_valid) {
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PMS5003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d,\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d,\"PB5\":%d,\"PB10\":%d}"), mqtt_data,
|
||||
pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
|
||||
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
|
||||
pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um, pms_data.particles_50um, pms_data.particles_100um);
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_PMS5003_SNS, mqtt_data,
|
||||
// pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
|
||||
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
|
||||
pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um, pms_data.particles_50um, pms_data.particles_100um);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_18
|
||||
|
||||
boolean Xsns18(byte function)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (pms_type) {
|
||||
switch (function) {
|
||||
case FUNC_INIT:
|
||||
PmsInit();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
PmsSecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
PmsShow(1);
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_APPEND:
|
||||
PmsShow(0);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_PMS5003
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
xsns_interface.ino - External sensor interface support for Sonoff-Tasmota
|
||||
xsns_interface.ino - Sensor interface support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends inspired by ESPEasy
|
||||
|
||||
@ -17,101 +17,187 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void XSnsInit()
|
||||
{
|
||||
for (byte i = 0; i < XSNS_MAX; i++) {
|
||||
xsns_func_ptr[i] = NULL;
|
||||
}
|
||||
xsns_present = 0;
|
||||
|
||||
boolean (* const xsns_func_ptr[])(byte) PROGMEM = { // Sensor Function Pointers for simple implementation of sensors
|
||||
#ifdef XSNS_01
|
||||
xsns_func_ptr[xsns_present++] = &Xsns01;
|
||||
&Xsns01,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_02
|
||||
xsns_func_ptr[xsns_present++] = &Xsns02;
|
||||
&Xsns02,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_03
|
||||
xsns_func_ptr[xsns_present++] = &Xsns03;
|
||||
&Xsns03,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_04
|
||||
xsns_func_ptr[xsns_present++] = &Xsns04;
|
||||
&Xsns04,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_05
|
||||
xsns_func_ptr[xsns_present++] = &Xsns05;
|
||||
&Xsns05,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_06
|
||||
xsns_func_ptr[xsns_present++] = &Xsns06;
|
||||
&Xsns06,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_07
|
||||
xsns_func_ptr[xsns_present++] = &Xsns07;
|
||||
&Xsns07,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_08
|
||||
xsns_func_ptr[xsns_present++] = &Xsns08;
|
||||
&Xsns08,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_09
|
||||
xsns_func_ptr[xsns_present++] = &Xsns09;
|
||||
&Xsns09,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_10
|
||||
xsns_func_ptr[xsns_present++] = &Xsns10;
|
||||
&Xsns10,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_11
|
||||
xsns_func_ptr[xsns_present++] = &Xsns11;
|
||||
&Xsns11,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_12
|
||||
xsns_func_ptr[xsns_present++] = &Xsns12;
|
||||
&Xsns12,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_13
|
||||
xsns_func_ptr[xsns_present++] = &Xsns13;
|
||||
&Xsns13,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_14
|
||||
xsns_func_ptr[xsns_present++] = &Xsns14;
|
||||
&Xsns14,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_15
|
||||
xsns_func_ptr[xsns_present++] = &Xsns15;
|
||||
&Xsns15,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_16
|
||||
xsns_func_ptr[xsns_present++] = &Xsns16;
|
||||
&Xsns16,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_17
|
||||
xsns_func_ptr[xsns_present++] = &Xsns17;
|
||||
&Xsns17,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_18
|
||||
xsns_func_ptr[xsns_present++] = &Xsns18;
|
||||
&Xsns18,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_19
|
||||
xsns_func_ptr[xsns_present++] = &Xsns19;
|
||||
&Xsns19,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_20
|
||||
xsns_func_ptr[xsns_present++] = &Xsns20;
|
||||
&Xsns20,
|
||||
#endif
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "Sensors found %d"), xsns_present);
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
#ifdef XSNS_21
|
||||
&Xsns21,
|
||||
#endif
|
||||
|
||||
XsnsCall(FUNC_INIT);
|
||||
}
|
||||
#ifdef XSNS_22
|
||||
&Xsns22,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_23
|
||||
&Xsns23,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_24
|
||||
&Xsns24,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_25
|
||||
&Xsns25,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_26
|
||||
&Xsns26,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_27
|
||||
&Xsns27,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_28
|
||||
&Xsns28,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_29
|
||||
&Xsns29,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_30
|
||||
&Xsns30,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_31
|
||||
&Xsns31,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_32
|
||||
&Xsns32,
|
||||
#endif
|
||||
|
||||
// Optional user defined sensors in range 91 - 99
|
||||
|
||||
#ifdef XSNS_91
|
||||
&Xsns91,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_92
|
||||
&Xsns92,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_93
|
||||
&Xsns93,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_94
|
||||
&Xsns94,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_95
|
||||
&Xsns95,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_96
|
||||
&Xsns96,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_97
|
||||
&Xsns97,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_98
|
||||
&Xsns98,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_99
|
||||
&Xsns99
|
||||
#endif
|
||||
};
|
||||
|
||||
const uint8_t xsns_present = sizeof(xsns_func_ptr) / sizeof(xsns_func_ptr[0]); // Number of External Sensors found
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Function call to all xsns
|
||||
*
|
||||
* FUNC_INIT
|
||||
* FUNC_PREP_BEFORE_TELEPERIOD
|
||||
* FUNC_SAVE_BEFORE_RESTART
|
||||
* FUNC_JSON_APPEND
|
||||
* FUNC_WEB_APPEND
|
||||
* return FUNC_COMMAND
|
||||
* FUNC_EVERY_SECOND
|
||||
* FUNC_EVERY_50_MSECOND
|
||||
\*********************************************************************************************/
|
||||
|
||||
boolean XsnsCall(byte Function)
|
||||
@ -119,7 +205,10 @@ boolean XsnsCall(byte Function)
|
||||
boolean result = false;
|
||||
|
||||
for (byte x = 0; x < xsns_present; x++) {
|
||||
xsns_func_ptr[x](Function);
|
||||
result = xsns_func_ptr[x](Function);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user