mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Merge branch 'development' into pre-release
This commit is contained in:
commit
c977069df5
3
.gitignore
vendored
3
.gitignore
vendored
@ -17,6 +17,7 @@ tasmota*.bin
|
||||
tasmota*.bin.gz
|
||||
tasmota*.map
|
||||
platformio_override.ini
|
||||
platformio_tasmota_cenv.ini
|
||||
|
||||
## Visual Studio Code specific ######
|
||||
.vscode
|
||||
@ -24,4 +25,4 @@ platformio_override.ini
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
*.bak
|
||||
*.code-workspace
|
||||
*.code-workspace
|
||||
|
@ -71,6 +71,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
||||
- Add commands ``NrfPage``, ``NrfIgnore``, ``NrfScan`` and ``NrfBeacon`` to NRF24 Bluetooth driver (#8075)
|
||||
- Add commands ``GlobalTemp`` and ``GlobalHum`` to init sensor data (#8152)
|
||||
- Add command ``SetOption41 <x>`` to force sending gratuitous ARP every <x> seconds
|
||||
- Add command ``SetOption73 1`` for button decoupling and send multi-press and hold MQTT messages by Federico Leoni (#8235)
|
||||
- Add command ``SetOption90 1`` to disable non-json MQTT messages (#8044)
|
||||
- Add command ``SetOption91 1`` to enable fading at startup / power on
|
||||
- Add command ``Sensor10 0/1/2`` to control BH1750 resolution - 0 = High (default), 1 = High2, 2 = Low (#8016)
|
||||
|
6
esp32_partition_app1984k_spiffs64k.csv
Normal file
6
esp32_partition_app1984k_spiffs64k.csv
Normal file
@ -0,0 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x1F0000,
|
||||
app1, app, ota_1, 0x200000, 0x1F0000,
|
||||
spiffs, data, spiffs, 0x3F0000,0x10000,
|
|
@ -1,6 +1,7 @@
|
||||
# TasmotaSerial
|
||||
|
||||
Implementation of software serial with hardware serial fallback library for the ESP8266
|
||||
Implementation of dual UART hardware serial for the ESP32
|
||||
|
||||
Allows for several instances to be active at the same time.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map for TasmotaSerial
|
||||
# (esp8266)
|
||||
# (esp8266 and esp32)
|
||||
#######################################
|
||||
|
||||
#######################################
|
@ -1,15 +1,17 @@
|
||||
{
|
||||
"name": "TasmotaSerial",
|
||||
"version": "2.4.1",
|
||||
"version": "3.0.0",
|
||||
"keywords": [
|
||||
"serial", "io", "TasmotaSerial"
|
||||
],
|
||||
"description": "Implementation of software serial with hardware serial fallback for ESP8266.",
|
||||
"description": "Implementation of software serial with hardware serial fallback for ESP8266 and ESP32.",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/arendst/Tasmota/lib/TasmotaSerial"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms": "espressif8266"
|
||||
"platforms": [
|
||||
"espressif8266", "espressif32"
|
||||
]
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
name=TasmotaSerial
|
||||
version=2.4.1
|
||||
version=3.0.0
|
||||
author=Theo Arends
|
||||
maintainer=Theo Arends <theo@arends.com>
|
||||
sentence=Implementation of software serial with hardware serial fallback for ESP8266.
|
||||
sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32.
|
||||
paragraph=
|
||||
category=Signal Input/Output
|
||||
url=
|
||||
architectures=esp8266
|
||||
architectures=esp8266,esp32
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
TasmotaSerial.cpp - Minimal implementation of software serial for Tasmota
|
||||
TasmotaSerial.cpp - Implementation of software serial with hardware serial fallback for Tasmota
|
||||
|
||||
Copyright (C) 2020 Theo Arends
|
||||
|
||||
@ -27,6 +27,8 @@ extern "C" {
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
#ifdef ESP8266
|
||||
|
||||
// for STAGE and pre-2.6, we can have a single wrapper using attachInterruptArg()
|
||||
void ICACHE_RAM_ATTR callRxRead(void *self) { ((TasmotaSerial*)self)->rxRead(); };
|
||||
|
||||
@ -79,6 +81,12 @@ static void (*ISRList[16])() = {
|
||||
tms_isr_15
|
||||
};
|
||||
|
||||
#else // ESP32
|
||||
|
||||
static int tasmota_serial_index = 2; // Allow UART2 and UART1 only
|
||||
|
||||
#endif // ESP8266
|
||||
|
||||
TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size)
|
||||
{
|
||||
m_valid = false;
|
||||
@ -87,12 +95,13 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
|
||||
m_stop_bits = 1;
|
||||
m_nwmode = nwmode;
|
||||
serial_buffer_size = buffer_size;
|
||||
if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) {
|
||||
return;
|
||||
}
|
||||
m_rx_pin = receive_pin;
|
||||
m_tx_pin = transmit_pin;
|
||||
m_in_pos = m_out_pos = 0;
|
||||
#ifdef ESP8266
|
||||
if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) {
|
||||
return;
|
||||
}
|
||||
if (hardware_fallback && (((3 == m_rx_pin) && (1 == m_tx_pin)) || ((3 == m_rx_pin) && (-1 == m_tx_pin)) || ((-1 == m_rx_pin) && (1 == m_tx_pin)))) {
|
||||
m_hardserial = true;
|
||||
}
|
||||
@ -120,11 +129,16 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
}
|
||||
}
|
||||
#else // ESP32
|
||||
if (transmit_pin > 33) { return; } // GPIO34 - GPIO39 are Input only
|
||||
m_hardserial = true;
|
||||
#endif // ESP8266 - ESP32
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
TasmotaSerial::~TasmotaSerial()
|
||||
{
|
||||
#ifdef ESP8266
|
||||
if (!m_hardserial) {
|
||||
if (m_rx_pin > -1) {
|
||||
detachInterrupt(m_rx_pin);
|
||||
@ -134,6 +148,7 @@ TasmotaSerial::~TasmotaSerial()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ESP8266
|
||||
}
|
||||
|
||||
bool TasmotaSerial::isValidGPIOpin(int pin)
|
||||
@ -144,17 +159,31 @@ bool TasmotaSerial::isValidGPIOpin(int pin)
|
||||
bool TasmotaSerial::begin(long speed, int stop_bits) {
|
||||
m_stop_bits = ((stop_bits -1) &1) +1;
|
||||
if (m_hardserial) {
|
||||
#ifdef ESP8266
|
||||
Serial.flush();
|
||||
if (2 == m_stop_bits) {
|
||||
Serial.begin(speed, SERIAL_8N2);
|
||||
} else {
|
||||
Serial.begin(speed, SERIAL_8N1);
|
||||
}
|
||||
#ifdef ESP8266
|
||||
if (m_hardswap) {
|
||||
Serial.swap();
|
||||
}
|
||||
#endif // ESP8266
|
||||
#else // ESP32
|
||||
if (tasmota_serial_index > 0) { // We only support UART1 and UART2 and keep UART0 for debugging
|
||||
m_uart = tasmota_serial_index;
|
||||
tasmota_serial_index--;
|
||||
TSerial = new HardwareSerial(m_uart);
|
||||
if (2 == m_stop_bits) {
|
||||
TSerial->begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin);
|
||||
} else {
|
||||
TSerial->begin(speed, SERIAL_8N1, m_rx_pin, m_tx_pin);
|
||||
}
|
||||
} else {
|
||||
m_valid = false;
|
||||
}
|
||||
// Serial.printf("TSR: Using UART%d\n", m_uart);
|
||||
#endif // ESP8266 - ESP32
|
||||
} else {
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() * 1000000 / speed;
|
||||
@ -170,12 +199,20 @@ bool TasmotaSerial::begin() {
|
||||
}
|
||||
|
||||
bool TasmotaSerial::hardwareSerial() {
|
||||
#ifdef ESP8266
|
||||
return m_hardserial;
|
||||
#else
|
||||
return false; // On ESP32 do not mess with Serial0 buffers
|
||||
#endif
|
||||
}
|
||||
|
||||
void TasmotaSerial::flush() {
|
||||
if (m_hardserial) {
|
||||
#ifdef ESP8266
|
||||
Serial.flush();
|
||||
#else
|
||||
TSerial->flush();
|
||||
#endif
|
||||
} else {
|
||||
m_in_pos = m_out_pos = 0;
|
||||
}
|
||||
@ -183,7 +220,11 @@ void TasmotaSerial::flush() {
|
||||
|
||||
int TasmotaSerial::peek() {
|
||||
if (m_hardserial) {
|
||||
#ifdef ESP8266
|
||||
return Serial.peek();
|
||||
#else
|
||||
return TSerial->peek();
|
||||
#endif
|
||||
} else {
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||
return m_buffer[m_out_pos];
|
||||
@ -193,7 +234,11 @@ int TasmotaSerial::peek() {
|
||||
int TasmotaSerial::read()
|
||||
{
|
||||
if (m_hardserial) {
|
||||
#ifdef ESP8266
|
||||
return Serial.read();
|
||||
#else
|
||||
return TSerial->read();
|
||||
#endif
|
||||
} else {
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||
uint32_t ch = m_buffer[m_out_pos];
|
||||
@ -205,7 +250,11 @@ int TasmotaSerial::read()
|
||||
int TasmotaSerial::available()
|
||||
{
|
||||
if (m_hardserial) {
|
||||
#ifdef ESP8266
|
||||
return Serial.available();
|
||||
#else
|
||||
return TSerial->available();
|
||||
#endif
|
||||
} else {
|
||||
int avail = m_in_pos - m_out_pos;
|
||||
if (avail < 0) avail += serial_buffer_size;
|
||||
@ -250,7 +299,11 @@ void TasmotaSerial::_fast_write(uint8_t b) {
|
||||
size_t TasmotaSerial::write(uint8_t b)
|
||||
{
|
||||
if (m_hardserial) {
|
||||
#ifdef ESP8266
|
||||
return Serial.write(b);
|
||||
#else
|
||||
return TSerial->write(b);
|
||||
#endif
|
||||
} else {
|
||||
if (-1 == m_tx_pin) return 0;
|
||||
if (m_high_speed) {
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
TasmotaSerial.h - Minimal implementation of software serial for Tasmota
|
||||
TasmotaSerial.h - Implementation of software serial with hardware serial fallback for Tasmota
|
||||
|
||||
Copyright (C) 2020 Theo Arends
|
||||
|
||||
@ -36,6 +36,10 @@
|
||||
#include <inttypes.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#ifdef ESP32
|
||||
#include <HardwareSerial.h>
|
||||
#endif
|
||||
|
||||
class TasmotaSerial : public Stream {
|
||||
public:
|
||||
TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0, int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE);
|
||||
@ -55,6 +59,10 @@ class TasmotaSerial : public Stream {
|
||||
|
||||
uint32_t getLoopReadMetric(void) const { return m_bit_follow_metric; }
|
||||
|
||||
#ifdef ESP32
|
||||
uint32_t getUart(void) const { return m_uart; }
|
||||
#endif
|
||||
|
||||
using Print::write;
|
||||
|
||||
private:
|
||||
@ -83,6 +91,12 @@ class TasmotaSerial : public Stream {
|
||||
uint8_t *m_buffer;
|
||||
|
||||
void _fast_write(uint8_t b); // IRAM minimized version
|
||||
|
||||
#ifdef ESP32
|
||||
HardwareSerial *TSerial;
|
||||
int m_uart = 0;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // TasmotaSerial_h
|
@ -20,71 +20,5 @@
|
||||
#include <rom/rtc.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "esp8266toEsp32.h"
|
||||
|
||||
// ESP Stuff
|
||||
struct rst_info resetInfo;
|
||||
|
||||
String ESP_getResetReason(void)
|
||||
{
|
||||
// CPU 0
|
||||
return String(rtc_get_reset_reason(0));
|
||||
}
|
||||
|
||||
String ESP_getResetInfo(void)
|
||||
{
|
||||
return String(PSTR("0"));
|
||||
}
|
||||
|
||||
uint32_t ESP_getBootVersion(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool ESP_rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ESP_rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void ESP_reset()
|
||||
{
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipId()
|
||||
{
|
||||
uint32_t id = 0;
|
||||
for (uint32_t i = 0; i < 17; i = i +8) {
|
||||
id |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
String String_ESP_getChipId()
|
||||
{
|
||||
uint64_t mac = ESP.getEfuseMac();
|
||||
return String(uint32_t(mac >> 32)) + String(uint32_t(mac));
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipRealSize()
|
||||
{
|
||||
return ESP.getFlashChipSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getSketchSize(void)
|
||||
{
|
||||
static uint32_t sketchsize = 0;
|
||||
|
||||
if (!sketchsize) {
|
||||
sketchsize = ESP.getSketchSize(); // This takes almost 2 seconds on an ESP32
|
||||
}
|
||||
return sketchsize;
|
||||
}
|
||||
|
@ -28,23 +28,6 @@
|
||||
|
||||
#include <Esp.h>
|
||||
|
||||
//
|
||||
// ESP32
|
||||
//
|
||||
#define ESP_flashReadHeader(offset, data, size) ESP32_flashRead(offset, data, size)
|
||||
#define ESP_flashRead(offset, data, size) ESP32_flashRead(offset, data, size)
|
||||
String ESP_getResetReason(void);
|
||||
uint32_t ESP_getBootVersion(void);
|
||||
bool ESP_rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size);
|
||||
bool ESP_rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size);
|
||||
void ESP_reset();
|
||||
String ESP_getResetInfo(void);
|
||||
uint32_t ESP_getFlashChipId();
|
||||
uint32_t ESP_getChipId();
|
||||
String String_ESP_getChipId();
|
||||
uint32_t ESP_getFlashChipRealSize();
|
||||
uint32_t ESP_getSketchSize();
|
||||
|
||||
// Analog
|
||||
inline void analogWrite(uint8_t pin, int val)
|
||||
{
|
||||
@ -67,7 +50,6 @@ typedef double real64_t;
|
||||
#define ETS_UART_INTR_DISABLE()
|
||||
#define ETS_UART_INTR_ENABLE()
|
||||
|
||||
#define getChipId() getEfuseMac()
|
||||
#define ESPhttpUpdate httpUpdate
|
||||
#define getFlashChipRealSize() getFlashChipSize()
|
||||
|
||||
@ -92,14 +74,13 @@ typedef int SerialConfig;
|
||||
|
||||
#undef LWIP_IPV6
|
||||
|
||||
struct rst_info
|
||||
{
|
||||
int reason;
|
||||
};
|
||||
|
||||
#define REASON_DEFAULT_RST 1
|
||||
#define REASON_EXT_SYS_RST 2
|
||||
#define REASON_DEEP_SLEEP_AWAKE 3
|
||||
#define REASON_DEFAULT_RST 0 // "Power on" normal startup by power on
|
||||
#define REASON_WDT_RST 1 // "Hardware Watchdog" hardware watch dog reset
|
||||
#define REASON_EXCEPTION_RST 2 // "Exception" exception reset, GPIO status won’t change
|
||||
#define REASON_SOFT_WDT_RST 3 // "Software Watchdog" software watch dog reset, GPIO status won’t change
|
||||
#define REASON_SOFT_RESTART 4 // "Software/System restart" software restart ,system_restart , GPIO status won’t change
|
||||
#define REASON_DEEP_SLEEP_AWAKE 5 // "Deep-Sleep Wake" wake up from deep-sleep
|
||||
#define REASON_EXT_SYS_RST 6 // "External System" external system reset
|
||||
|
||||
// memmove ...
|
||||
#define memcpy_P memcpy
|
||||
|
@ -28,6 +28,7 @@ def bin_map_copy(source, target, env):
|
||||
shutil.copy(str(target[0]), bin_file)
|
||||
|
||||
# copy firmware.map to map/<variant>.map
|
||||
shutil.copy("firmware.map", map_file)
|
||||
if os.path.isfile("firmware.map"):
|
||||
shutil.move("firmware.map", map_file)
|
||||
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_map_copy])
|
||||
|
@ -87,17 +87,21 @@ extra_scripts = pio/strip-floats.py
|
||||
pio/name-firmware.py
|
||||
pio/gzip-firmware.py
|
||||
|
||||
[esp82xx_defaults]
|
||||
build_flags = -D NDEBUG
|
||||
-mtarget-align
|
||||
-Wl,-Map,firmware.map
|
||||
-DFP_IN_IROM
|
||||
; new mechanism to set the IRremoteESP8266 supported protocols: none except HASH, NEC, RC5, RC6
|
||||
-D_IR_ENABLE_DEFAULT_=false
|
||||
[esp_defaults]
|
||||
build_flags = -D_IR_ENABLE_DEFAULT_=false
|
||||
-DDECODE_HASH=true -DDECODE_NEC=true -DSEND_NEC=true
|
||||
-DDECODE_RC5=true -DSEND_RC5=true -DDECODE_RC6=true -DSEND_RC6=true
|
||||
; new mechanism to set the IRremoteESP8266 supported protocols: none except HASH, NEC, RC5, RC6
|
||||
|
||||
[irremoteesp8266_full]
|
||||
[esp82xx_defaults]
|
||||
build_flags = ${esp_defaults.build_flags}
|
||||
-Wl,-Map,firmware.map
|
||||
-D NDEBUG
|
||||
-mtarget-align
|
||||
-DFP_IN_IROM
|
||||
|
||||
|
||||
[irremoteesp_full]
|
||||
build_flags = -DUSE_IR_REMOTE_FULL
|
||||
-U_IR_ENABLE_DEFAULT_
|
||||
-DDECODE_PRONTO=false -DSEND_PRONTO=false
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
[platformio]
|
||||
extra_configs = platformio_tasmota_env32.ini
|
||||
platformio_tasmota_cenv.ini
|
||||
|
||||
; *** Build/upload environment
|
||||
default_envs =
|
||||
@ -54,7 +55,7 @@ build_flags = ${core_active.build_flags}
|
||||
upload_port = COM5
|
||||
|
||||
extra_scripts = ${scripts_defaults.extra_scripts}
|
||||
pio/obj-dump.py
|
||||
; pio/obj-dump.py
|
||||
|
||||
; *** Upload file to OTA server using SCP
|
||||
;upload_port = user@host:/path
|
||||
@ -227,9 +228,10 @@ build_type = debug
|
||||
|
||||
[common32]
|
||||
platform = espressif32@1.12.0
|
||||
platform_packages =
|
||||
platform_packages = tool-esptoolpy@1.20800.0
|
||||
board = wemos_d1_mini32
|
||||
board_build.ldscript = esp32_out.ld
|
||||
board_build.partitions = esp32_partition_app1984k_spiffs64k.csv
|
||||
board_build.flash_mode = ${common.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common.board_build.f_cpu}
|
||||
build_unflags = ${common.build_unflags}
|
||||
@ -239,7 +241,7 @@ upload_resetmethod = ${common.upload_resetmethod}
|
||||
upload_speed = 921600
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
|
||||
build_flags =
|
||||
build_flags = ${esp_defaults.build_flags}
|
||||
-D BUFFER_LENGTH=128
|
||||
-D MQTT_MAX_PACKET_SIZE=1200
|
||||
-D uint32=uint32_t
|
||||
|
@ -32,10 +32,10 @@ build_flags = ${common.build_flags} -DFIRMWARE_SENSORS
|
||||
build_flags = ${common.build_flags} -DFIRMWARE_DISPLAYS
|
||||
|
||||
[env:tasmota-ir]
|
||||
build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags} -DFIRMWARE_IR
|
||||
build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR
|
||||
|
||||
[env:tasmota-ircustom]
|
||||
build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags}
|
||||
build_flags = ${common.build_flags} ${irremoteesp_full.build_flags}
|
||||
|
||||
[env:tasmota-BG]
|
||||
build_flags = ${common.build_flags} -DMY_LANGUAGE=bg-BG
|
||||
|
@ -4,6 +4,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -22,6 +23,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -40,6 +42,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -58,6 +61,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -76,6 +80,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -94,6 +99,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -112,6 +118,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -122,7 +129,7 @@ extra_scripts = ${common32.extra_scripts}
|
||||
lib_extra_dirs = ${common32.lib_extra_dirs}
|
||||
lib_ignore = ${common32.lib_ignore}
|
||||
build_unflags = ${common32.build_unflags}
|
||||
build_flags = ${common32.build_flags} ${irremoteesp8266_full.build_flags} -DFIRMWARE_IR
|
||||
build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR
|
||||
|
||||
[env:tasmota32-ircustom]
|
||||
framework = ${common.framework}
|
||||
@ -130,6 +137,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -140,7 +148,7 @@ extra_scripts = ${common32.extra_scripts}
|
||||
lib_extra_dirs = ${common32.lib_extra_dirs}
|
||||
lib_ignore = ${common32.lib_ignore}
|
||||
build_unflags = ${common32.build_unflags}
|
||||
build_flags = ${common32.build_flags} ${irremoteesp8266_full.build_flags}
|
||||
build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags}
|
||||
|
||||
[env:tasmota32-BG]
|
||||
framework = ${common.framework}
|
||||
@ -148,6 +156,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -166,6 +175,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -184,6 +194,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -202,6 +213,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -220,6 +232,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -238,6 +251,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -256,6 +270,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -274,6 +289,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -292,6 +308,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -310,6 +327,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -328,6 +346,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -346,6 +365,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -364,6 +384,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -382,6 +403,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -400,6 +422,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -418,6 +441,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -436,6 +460,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -454,6 +479,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -472,6 +498,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -490,6 +517,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -508,6 +536,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
@ -526,6 +555,7 @@ platform = ${common32.platform}
|
||||
platform_packages = ${common32.platform_packages}
|
||||
board = ${common32.board}
|
||||
board_build.ldscript = ${common32.board_build.ldscript}
|
||||
board_build.partitions = ${common32.board_build.partitions}
|
||||
board_build.flash_mode = ${common32.board_build.flash_mode}
|
||||
board_build.f_cpu = ${common32.board_build.f_cpu}
|
||||
monitor_speed = ${common32.monitor_speed}
|
||||
|
@ -6,6 +6,12 @@
|
||||
|
||||
- Release Fred
|
||||
|
||||
### 8.2.0.4 20200417
|
||||
|
||||
- Fix Zigbee DimmerUp/DimmerDown malformed
|
||||
- Add config version tag
|
||||
- Add command ``SetOption73 1`` for button decoupling and send multi-press and hold MQTT messages by Federico Leoni (#8235)
|
||||
|
||||
### 8.2.0.3 20200329
|
||||
|
||||
- Change light scheme 2,3,4 cycle time speed from 24,48,72,... seconds to 4,6,12,24,36,48,... seconds (#8034)
|
||||
|
@ -19,6 +19,8 @@
|
||||
Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
|
||||
*/
|
||||
|
||||
#ifdef ESP8266
|
||||
|
||||
// Use patched Parsing.cpp to fix ALEXA parsing issue in v2.4.2
|
||||
#include <core_version.h>
|
||||
#if defined(ARDUINO_ESP8266_RELEASE_2_4_2)
|
||||
@ -620,4 +622,6 @@ bool ESP8266WebServer::_parseFormUploadAborted(){
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // ARDUINO_ESP8266_RELEASE
|
||||
#endif // ARDUINO_ESP8266_RELEASE
|
||||
|
||||
#endif // ESP8266
|
||||
|
@ -297,6 +297,7 @@
|
||||
#define D_CMND_DEVGROUP_NAME "DevGroupName"
|
||||
#define D_CMND_DEVGROUP_SEND "DevGroupSend"
|
||||
#define D_CMND_DEVGROUP_SHARE "DevGroupShare"
|
||||
#define D_CMND_DEVGROUPSTATUS "DevGroupStatus"
|
||||
#define D_CMND_SERIALSEND "SerialSend"
|
||||
#define D_CMND_SERIALDELIMITER "SerialDelimiter"
|
||||
#define D_CMND_BAUDRATE "Baudrate"
|
||||
|
@ -567,8 +567,8 @@
|
||||
#define D_SENSOR_SPI_MOSI "SPI - MOSI"
|
||||
#define D_SENSOR_SPI_CLK "SPI - CLK"
|
||||
#define D_SENSOR_BACKLIGHT "Retroilluminazione"
|
||||
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
|
||||
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
|
||||
#define D_SENSOR_PMS5003_TX "PMS5003 - TX"
|
||||
#define D_SENSOR_PMS5003_RX "PMS5003 - RX"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 - RX"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 - TX"
|
||||
#define D_SENSOR_HPMA_RX "HPMA - RX"
|
||||
|
@ -391,7 +391,7 @@
|
||||
#define SUNRISE_DAWN_ANGLE DAWN_NORMAL // Select desired Dawn Angle from (DAWN_NORMAL, DAWN_CIVIL, DAWN_NAUTIC, DAWN_ASTRONOMIC)
|
||||
|
||||
// -- Ping ----------------------------------------
|
||||
// #define USE_PING // Enable Ping command (+3k code)
|
||||
// #define USE_PING // Enable Ping command (+2k code)
|
||||
|
||||
// -- Rules or Script ----------------------------
|
||||
// Select none or only one of the below defines
|
||||
|
@ -86,7 +86,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t energy_weekend : 1; // bit 20 (v6.6.0.8) - CMND_TARIFF
|
||||
uint32_t dds2382_model : 1; // bit 21 (v6.6.0.14) - SetOption71 - Select different Modbus registers for Active Energy (#6531)
|
||||
uint32_t hardware_energy_total : 1; // bit 22 (v6.6.0.15) - SetOption72 - Enable hardware energy total counter as reference (#6561)
|
||||
uint32_t mqtt_buttons : 1; // bit 23 (v8.2.0.3) - SetOption73 - Detach buttons from relays and enable MQTT action state for multipress
|
||||
uint32_t mqtt_buttons : 1; // bit 23 (v8.2.0.3) - SetOption73 - Detach buttons from relays and enable MQTT action state for multipress
|
||||
uint32_t ds18x20_internal_pullup : 1; // bit 24 (v7.0.0.1) - SetOption74 - Enable internal pullup for single DS18x20 sensor
|
||||
uint32_t grouptopic_mode : 1; // bit 25 (v7.0.0.1) - SetOption75 - GroupTopic replaces %topic% (0) or fixed topic cmnd/grouptopic (1)
|
||||
uint32_t bootcount_update : 1; // bit 26 (v7.0.0.4) - SetOption76 - Enable incrementing bootcount when deepsleep is enabled
|
||||
@ -245,7 +245,7 @@ typedef struct {
|
||||
} EnergyUsage;
|
||||
|
||||
|
||||
typedef struct PACKED {
|
||||
typedef struct {
|
||||
uint8_t fnid = 0;
|
||||
uint8_t dpid = 0;
|
||||
} TuyaFnidDpidMap;
|
||||
@ -253,7 +253,7 @@ typedef struct PACKED {
|
||||
const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017)
|
||||
const uint8_t MAX_TUYA_FUNCTIONS = 16;
|
||||
|
||||
struct PACKED SYSCFG {
|
||||
struct {
|
||||
uint16_t cfg_holder; // 000 v6 header
|
||||
uint16_t cfg_size; // 002
|
||||
unsigned long save_flag; // 004
|
||||
@ -369,7 +369,13 @@ struct PACKED SYSCFG {
|
||||
uint8_t module; // 474
|
||||
uint8_t ws_color[4][3]; // 475
|
||||
uint8_t ws_width[3]; // 481
|
||||
myio my_gp; // 484
|
||||
|
||||
#ifdef ESP8266
|
||||
myio my_gp; // 484 - 17 bytes (ESP8266)
|
||||
#else // ESP32
|
||||
uint8_t free_esp32_484[17]; // 484
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
uint8_t my_adc0; // 495
|
||||
uint16_t light_pixels; // 496
|
||||
uint8_t light_color[5]; // 498
|
||||
@ -397,7 +403,14 @@ struct PACKED SYSCFG {
|
||||
uint32_t ip_address[4]; // 544
|
||||
unsigned long energy_kWhtotal; // 554
|
||||
|
||||
#ifdef ESP8266
|
||||
char ex_mqtt_fulltopic[100]; // 558
|
||||
#else // ESP32
|
||||
myio my_gp; // 558 - 40 bytes (ESP32)
|
||||
mytmplt user_template; // 580 - 37 bytes (ESP32)
|
||||
|
||||
uint8_t free_esp32_5a5[23]; // 5A5
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
SysBitfield2 flag2; // 5BC
|
||||
unsigned long pulse_counter[MAX_COUNTERS]; // 5C0
|
||||
@ -423,7 +436,12 @@ struct PACKED SYSCFG {
|
||||
|
||||
char user_template_name[15]; // 720 15 bytes - Backward compatibility since v8.2.0.3
|
||||
|
||||
mytmplt user_template; // 72F 14 bytes
|
||||
#ifdef ESP8266
|
||||
mytmplt user_template; // 72F 14 bytes (ESP8266)
|
||||
#else // ESP32
|
||||
uint8_t free_esp32_72f[14]; // 72F
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
uint8_t novasds_startingoffset; // 73D
|
||||
uint8_t web_color[18][3]; // 73E
|
||||
uint16_t display_width; // 774
|
||||
@ -506,9 +524,11 @@ struct PACKED SYSCFG {
|
||||
uint8_t zb_channel; // F32
|
||||
uint8_t zb_free_byte; // F33
|
||||
uint16_t pms_wake_interval; // F34
|
||||
uint8_t config_version; // F36
|
||||
|
||||
uint8_t free_f36[130]; // F36
|
||||
uint8_t free_f37[129]; // F37 - Decrement if adding new Setting variables just above and below
|
||||
|
||||
// Only 32 bit boundary variables below
|
||||
uint16_t pulse_counter_debounce_low; // FB8
|
||||
uint16_t pulse_counter_debounce_high; // FBA
|
||||
uint32_t keeloq_master_msb; // FBC
|
||||
@ -525,13 +545,17 @@ struct PACKED SYSCFG {
|
||||
uint32_t cfg_crc32; // FFC
|
||||
} Settings;
|
||||
|
||||
struct RTCRBT {
|
||||
typedef struct {
|
||||
uint16_t valid; // 280 (RTC memory offset 100 - sizeof(RTCRBT))
|
||||
uint8_t fast_reboot_count; // 282
|
||||
uint8_t free_003[1]; // 283
|
||||
} RtcReboot;
|
||||
} TRtcReboot;
|
||||
TRtcReboot RtcReboot;
|
||||
#ifdef ESP32
|
||||
RTC_NOINIT_ATTR TRtcReboot RtcDataReboot;
|
||||
#endif
|
||||
|
||||
struct RTCMEM {
|
||||
typedef struct {
|
||||
uint16_t valid; // 290 (RTC memory offset 100)
|
||||
uint8_t oswatch_blocked_loop; // 292
|
||||
uint8_t ota_loader; // 293
|
||||
@ -547,7 +571,11 @@ struct RTCMEM {
|
||||
|
||||
uint8_t free_022[22]; // 2D6
|
||||
// 2EC - 2FF free locations
|
||||
} RtcSettings;
|
||||
} TRtcSettings;
|
||||
TRtcSettings RtcSettings;
|
||||
#ifdef ESP32
|
||||
RTC_NOINIT_ATTR TRtcSettings RtcDataSettings;
|
||||
#endif
|
||||
|
||||
struct TIME_T {
|
||||
uint8_t second;
|
||||
|
@ -30,7 +30,7 @@ uint32_t GetRtcSettingsCrc(void)
|
||||
uint32_t crc = 0;
|
||||
uint8_t *bytes = (uint8_t*)&RtcSettings;
|
||||
|
||||
for (uint32_t i = 0; i < sizeof(RTCMEM); i++) {
|
||||
for (uint32_t i = 0; i < sizeof(RtcSettings); i++) {
|
||||
crc += bytes[i]*(i+1);
|
||||
}
|
||||
return crc;
|
||||
@ -40,16 +40,24 @@ void RtcSettingsSave(void)
|
||||
{
|
||||
if (GetRtcSettingsCrc() != rtc_settings_crc) {
|
||||
RtcSettings.valid = RTC_MEM_VALID;
|
||||
ESP_rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
|
||||
#ifdef ESP8266
|
||||
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RtcSettings));
|
||||
#else
|
||||
RtcDataSettings = RtcSettings;
|
||||
#endif
|
||||
rtc_settings_crc = GetRtcSettingsCrc();
|
||||
}
|
||||
}
|
||||
|
||||
void RtcSettingsLoad(void)
|
||||
{
|
||||
ESP_rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); // 0x290
|
||||
#ifdef ESP8266
|
||||
ESP.rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RtcSettings)); // 0x290
|
||||
#else
|
||||
RtcSettings = RtcDataSettings;
|
||||
#endif
|
||||
if (RtcSettings.valid != RTC_MEM_VALID) {
|
||||
memset(&RtcSettings, 0, sizeof(RTCMEM));
|
||||
memset(&RtcSettings, 0, sizeof(RtcSettings));
|
||||
RtcSettings.valid = RTC_MEM_VALID;
|
||||
RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday;
|
||||
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
|
||||
@ -77,7 +85,7 @@ uint32_t GetRtcRebootCrc(void)
|
||||
uint32_t crc = 0;
|
||||
uint8_t *bytes = (uint8_t*)&RtcReboot;
|
||||
|
||||
for (uint32_t i = 0; i < sizeof(RTCRBT); i++) {
|
||||
for (uint32_t i = 0; i < sizeof(RtcReboot); i++) {
|
||||
crc += bytes[i]*(i+1);
|
||||
}
|
||||
return crc;
|
||||
@ -87,7 +95,11 @@ void RtcRebootSave(void)
|
||||
{
|
||||
if (GetRtcRebootCrc() != rtc_reboot_crc) {
|
||||
RtcReboot.valid = RTC_MEM_VALID;
|
||||
ESP_rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT));
|
||||
#ifdef ESP8266
|
||||
ESP.rtcUserMemoryWrite(100 - sizeof(RtcReboot), (uint32_t*)&RtcReboot, sizeof(RtcReboot));
|
||||
#else
|
||||
RtcDataReboot = RtcReboot;
|
||||
#endif
|
||||
rtc_reboot_crc = GetRtcRebootCrc();
|
||||
}
|
||||
}
|
||||
@ -100,9 +112,13 @@ void RtcRebootReset(void)
|
||||
|
||||
void RtcRebootLoad(void)
|
||||
{
|
||||
ESP_rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); // 0x280
|
||||
#ifdef ESP8266
|
||||
ESP.rtcUserMemoryRead(100 - sizeof(RtcReboot), (uint32_t*)&RtcReboot, sizeof(RtcReboot)); // 0x280
|
||||
#else
|
||||
RtcReboot = RtcDataReboot;
|
||||
#endif
|
||||
if (RtcReboot.valid != RTC_MEM_VALID) {
|
||||
memset(&RtcReboot, 0, sizeof(RTCRBT));
|
||||
memset(&RtcReboot, 0, sizeof(RtcReboot));
|
||||
RtcReboot.valid = RTC_MEM_VALID;
|
||||
// RtcReboot.fast_reboot_count = 0; // Explicit by memset
|
||||
RtcRebootSave();
|
||||
@ -289,7 +305,7 @@ uint16_t GetCfgCrc16(uint8_t *bytes, uint32_t size)
|
||||
uint16_t GetSettingsCrc(void)
|
||||
{
|
||||
// Fix miscalculation if previous Settings was 3584 and current Settings is 4096 between 0x06060007 and 0x0606000A
|
||||
uint32_t size = ((Settings.version < 0x06060007) || (Settings.version > 0x0606000A)) ? 3584 : sizeof(SYSCFG);
|
||||
uint32_t size = ((Settings.version < 0x06060007) || (Settings.version > 0x0606000A)) ? 3584 : sizeof(Settings);
|
||||
return GetCfgCrc16((uint8_t*)&Settings, size);
|
||||
}
|
||||
|
||||
@ -309,7 +325,7 @@ uint32_t GetCfgCrc32(uint8_t *bytes, uint32_t size)
|
||||
|
||||
uint32_t GetSettingsCrc32(void)
|
||||
{
|
||||
return GetCfgCrc32((uint8_t*)&Settings, sizeof(SYSCFG) -4); // Skip crc32
|
||||
return GetCfgCrc32((uint8_t*)&Settings, sizeof(Settings) -4); // Skip crc32
|
||||
}
|
||||
|
||||
void SettingsSaveAll(void)
|
||||
@ -335,7 +351,11 @@ void UpdateQuickPowerCycle(bool update)
|
||||
uint32_t pc_register;
|
||||
uint32_t pc_location = SETTINGS_LOCATION - CFG_ROTATES;
|
||||
|
||||
#ifdef ESP8266
|
||||
ESP.flashRead(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
#else
|
||||
QPCRead(&pc_register, sizeof(pc_register));
|
||||
#endif
|
||||
if (update && ((pc_register & 0xFFFFFFF0) == 0xFFA55AB0)) {
|
||||
uint32_t counter = ((pc_register & 0xF) << 1) & 0xF;
|
||||
if (0 == counter) { // 4 power cycles in a row
|
||||
@ -343,16 +363,24 @@ void UpdateQuickPowerCycle(bool update)
|
||||
EspRestart(); // And restart
|
||||
} else {
|
||||
pc_register = 0xFFA55AB0 | counter;
|
||||
#ifdef ESP8266
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
#else
|
||||
QPCWrite(&pc_register, sizeof(pc_register));
|
||||
#endif
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Flag %02X"), counter);
|
||||
}
|
||||
}
|
||||
else if (pc_register != 0xFFA55ABF) {
|
||||
pc_register = 0xFFA55ABF;
|
||||
#ifdef ESP8266
|
||||
// Assume flash is default all ones and setting a bit to zero does not need an erase
|
||||
if (ESP.flashEraseSector(pc_location)) {
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
}
|
||||
#else
|
||||
QPCWrite(&pc_register, sizeof(pc_register));
|
||||
#endif
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Reset"));
|
||||
}
|
||||
}
|
||||
@ -485,13 +513,13 @@ void SettingsSave(uint8_t rotate)
|
||||
} else {
|
||||
Settings.cfg_timestamp++;
|
||||
}
|
||||
Settings.cfg_size = sizeof(SYSCFG);
|
||||
Settings.cfg_size = sizeof(Settings);
|
||||
Settings.cfg_crc = GetSettingsCrc(); // Keep for backward compatibility in case of fall-back just after upgrade
|
||||
Settings.cfg_crc32 = GetSettingsCrc32();
|
||||
|
||||
#ifdef ESP8266
|
||||
if (ESP.flashEraseSector(settings_location)) {
|
||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
|
||||
}
|
||||
|
||||
if (!stop_flash_rotate && rotate) {
|
||||
@ -500,12 +528,12 @@ void SettingsSave(uint8_t rotate)
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(Settings));
|
||||
#else // ESP32
|
||||
SettingsSaveMain(&Settings, sizeof(SYSCFG));
|
||||
SettingsWrite(&Settings, sizeof(Settings));
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "Saved, " D_COUNT " %d, " D_BYTES " %d"), Settings.save_flag, sizeof(Settings));
|
||||
#endif // ESP8266
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG));
|
||||
|
||||
settings_crc32 = Settings.cfg_crc32;
|
||||
}
|
||||
#endif // FIRMWARE_MINIMAL
|
||||
@ -514,8 +542,9 @@ void SettingsSave(uint8_t rotate)
|
||||
|
||||
void SettingsLoad(void)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
// Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate
|
||||
struct SYSCFGH {
|
||||
struct {
|
||||
uint16_t cfg_holder; // 000
|
||||
uint16_t cfg_size; // 002
|
||||
unsigned long save_flag; // 004
|
||||
@ -527,7 +556,7 @@ void SettingsLoad(void)
|
||||
uint16_t cfg_holder = 0;
|
||||
for (uint32_t i = 0; i < CFG_ROTATES; i++) {
|
||||
flash_location--;
|
||||
ESP_flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
|
||||
bool valid = false;
|
||||
if (Settings.version > 0x06000000) {
|
||||
bool almost_valid = (Settings.cfg_crc32 == GetSettingsCrc32());
|
||||
@ -538,7 +567,7 @@ void SettingsLoad(void)
|
||||
if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder
|
||||
valid = (cfg_holder == Settings.cfg_holder);
|
||||
} else {
|
||||
ESP_flashReadHeader((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
|
||||
ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(_SettingsH));
|
||||
valid = (Settings.cfg_holder == _SettingsH.cfg_holder);
|
||||
}
|
||||
if (valid) {
|
||||
@ -550,13 +579,16 @@ void SettingsLoad(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delay(1);
|
||||
}
|
||||
if (settings_location > 0) {
|
||||
ESP_flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
|
||||
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
|
||||
}
|
||||
#else // ESP32
|
||||
SettingsRead(&Settings, sizeof(Settings));
|
||||
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded, " D_COUNT " %lu"), Settings.save_flag);
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
#ifndef FIRMWARE_MINIMAL
|
||||
if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h
|
||||
@ -667,10 +699,10 @@ void SettingsDefault(void)
|
||||
|
||||
void SettingsDefaultSet1(void)
|
||||
{
|
||||
memset(&Settings, 0x00, sizeof(SYSCFG));
|
||||
memset(&Settings, 0x00, sizeof(Settings));
|
||||
|
||||
Settings.cfg_holder = (uint16_t)CFG_HOLDER;
|
||||
Settings.cfg_size = sizeof(SYSCFG);
|
||||
Settings.cfg_size = sizeof(Settings);
|
||||
// Settings.save_flag = 0;
|
||||
Settings.version = VERSION;
|
||||
// Settings.bootcount = 0;
|
||||
@ -679,7 +711,7 @@ void SettingsDefaultSet1(void)
|
||||
|
||||
void SettingsDefaultSet2(void)
|
||||
{
|
||||
memset((char*)&Settings +16, 0x00, sizeof(SYSCFG) -16);
|
||||
memset((char*)&Settings +16, 0x00, sizeof(Settings) -16);
|
||||
|
||||
Settings.flag.stop_flash_rotate = APP_FLASH_CYCLE;
|
||||
Settings.flag.global_state = APP_ENABLE_LEDLINK;
|
||||
@ -1048,7 +1080,7 @@ void SettingsDelta(void)
|
||||
|
||||
#ifdef ESP8266
|
||||
if (Settings.version < 0x06000000) {
|
||||
Settings.cfg_size = sizeof(SYSCFG);
|
||||
Settings.cfg_size = sizeof(Settings);
|
||||
Settings.cfg_crc = GetSettingsCrc();
|
||||
}
|
||||
if (Settings.version < 0x06000002) {
|
||||
@ -1132,7 +1164,7 @@ void SettingsDelta(void)
|
||||
Settings.param[P_OVER_TEMP] = ENERGY_OVERTEMP;
|
||||
}
|
||||
if (Settings.version < 0x06060007) {
|
||||
memset((char*)&Settings +0xE00, 0x00, sizeof(SYSCFG) -0xE00);
|
||||
memset((char*)&Settings +0xE00, 0x00, sizeof(Settings) -0xE00);
|
||||
}
|
||||
if (Settings.version < 0x06060008) {
|
||||
// Move current tuya dimmer range to the new param.
|
||||
@ -1337,6 +1369,15 @@ void SettingsDelta(void)
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
if (Settings.version < 0x08020004) {
|
||||
#ifdef ESP8266
|
||||
Settings.config_version = 0; // ESP8266 (Has been 0 for long time)
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
Settings.config_version = 1; // ESP32
|
||||
#endif // ESP32
|
||||
}
|
||||
|
||||
Settings.version = VERSION;
|
||||
SettingsSave(1);
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ uint32_t ResetReason(void)
|
||||
REASON_DEEP_SLEEP_AWAKE = 5, // "Deep-Sleep Wake" wake up from deep-sleep
|
||||
REASON_EXT_SYS_RST = 6 // "External System" external system reset
|
||||
*/
|
||||
return resetInfo.reason;
|
||||
return ESP_ResetInfoReason();
|
||||
}
|
||||
|
||||
String GetResetReason(void)
|
||||
@ -1127,7 +1127,11 @@ void ModuleGpios(myio *gp)
|
||||
if (USER_MODULE == Settings.module) {
|
||||
memcpy(&src, &Settings.user_template.gp, sizeof(mycfgio));
|
||||
} else {
|
||||
#ifdef ESP8266
|
||||
memcpy_P(&src, &kModules[Settings.module].gp, sizeof(mycfgio));
|
||||
#else // ESP32
|
||||
memcpy_P(&src, &kModules.gp, sizeof(mycfgio));
|
||||
#endif // ESP8266 - ESP32
|
||||
}
|
||||
// 11 85 00 85 85 00 00 00 15 38 85 00 00 81
|
||||
|
||||
@ -1135,13 +1139,8 @@ void ModuleGpios(myio *gp)
|
||||
|
||||
uint32_t j = 0;
|
||||
for (uint32_t i = 0; i < sizeof(mycfgio); i++) {
|
||||
#ifdef ESP8266
|
||||
if (6 == i) { j = 9; }
|
||||
if (8 == i) { j = 12; }
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
if (6 == i) { j = 12; }
|
||||
#endif // ESP32
|
||||
dest[j] = src[i];
|
||||
j++;
|
||||
}
|
||||
@ -1154,11 +1153,24 @@ gpio_flag ModuleFlag(void)
|
||||
{
|
||||
gpio_flag flag;
|
||||
|
||||
#ifdef ESP8266
|
||||
if (USER_MODULE == Settings.module) {
|
||||
flag = Settings.user_template.flag;
|
||||
} else {
|
||||
memcpy_P(&flag, &kModules[Settings.module].flag, sizeof(gpio_flag));
|
||||
}
|
||||
#else // ESP32
|
||||
if (USER_MODULE == Settings.module) {
|
||||
/*
|
||||
gpio_flag gpio_adc0;
|
||||
memcpy_P(&gpio_adc0, &Settings.user_template.gp + ADC0_PIN - MIN_FLASH_PINS, sizeof(gpio_flag));
|
||||
flag = Settings.user_template.flag.data + gpio_adc0.data;
|
||||
*/
|
||||
memcpy_P(&flag, &Settings.user_template.gp + ADC0_PIN - MIN_FLASH_PINS, sizeof(gpio_flag));
|
||||
} else {
|
||||
memcpy_P(&flag, &kModules.gp + ADC0_PIN - MIN_FLASH_PINS, sizeof(gpio_flag));
|
||||
}
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
return flag;
|
||||
}
|
||||
@ -1169,7 +1181,11 @@ void ModuleDefault(uint32_t module)
|
||||
Settings.user_template_base = module;
|
||||
char name[TOPSZ];
|
||||
SettingsUpdateText(SET_TEMPLATE_NAME, GetTextIndexed(name, sizeof(name), module, kModuleNames));
|
||||
#ifdef ESP8266
|
||||
memcpy_P(&Settings.user_template, &kModules[module], sizeof(mytmplt));
|
||||
#else // ESP32
|
||||
memcpy_P(&Settings.user_template, &kModules, sizeof(mytmplt));
|
||||
#endif // ESP8266 - ESP32
|
||||
}
|
||||
|
||||
void SetModuleType(void)
|
||||
@ -1179,12 +1195,7 @@ void SetModuleType(void)
|
||||
|
||||
bool FlashPin(uint32_t pin)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
return (((pin > 5) && (pin < 9)) || (11 == pin));
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
return ((pin > 5) && (pin < 12));
|
||||
#endif // ESP32
|
||||
}
|
||||
|
||||
uint8_t ValidPin(uint32_t pin, uint32_t gpio)
|
||||
@ -1193,14 +1204,12 @@ uint8_t ValidPin(uint32_t pin, uint32_t gpio)
|
||||
return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
// if (!is_8285 && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
|
||||
if ((WEMOS == Settings.module) && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
|
||||
if ((pin == 9) || (pin == 10)) {
|
||||
return GPIO_NONE; // Disable possible flash GPIO9 and GPIO10
|
||||
}
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
return gpio;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define BUTTON_V1
|
||||
//#define BUTTON_V1
|
||||
#ifdef BUTTON_V1
|
||||
/*********************************************************************************************\
|
||||
* Button support
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
support_button.ino - button support for Tasmota
|
||||
support_button_v2.ino - button support for Tasmota
|
||||
|
||||
Copyright (C) 2020 Theo Arends
|
||||
Copyright (C) 2020 Federico Leoni and 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
|
||||
@ -17,18 +17,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//#define BUTTON_V2
|
||||
#define BUTTON_V2
|
||||
#ifdef BUTTON_V2
|
||||
/*********************************************************************************************\
|
||||
* Button support
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define MAX_BUTTON_COMMANDS_V2 3 // Max number of button commands supported
|
||||
#define MAX_RELAY_BUTTON1 4 // Max number of relay controlled by button1
|
||||
#define MAX_RELAY_BUTTON1 5 // Max number of relay controlled by BUTTON1
|
||||
|
||||
const char kCommands[] PROGMEM =
|
||||
D_CMND_WIFICONFIG " 2|" D_CMND_RESTART " 1|" D_CMND_UPGRADE " 1";
|
||||
//D_CMND_WIFICONFIG " 2|" D_CMND_WIFICONFIG " 2|" D_CMND_WIFICONFIG " 2|" D_CMND_RESTART " 1|" D_CMND_UPGRADE " 1";
|
||||
const char kMultiPress[] PROGMEM =
|
||||
"|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|";
|
||||
|
||||
@ -103,11 +99,9 @@ uint8_t ButtonSerial(uint8_t serial_in_byte)
|
||||
* Button handler with single press only or multi-press and hold on all buttons
|
||||
*
|
||||
* ButtonDebounce (50) - Debounce time in mSec
|
||||
* SetOption1 (0) - If set do not execute config commands
|
||||
* SetOption11 (0) - If set perform single press action on double press and reverse
|
||||
* SetOption1 (0) - If set do not execute commands WifiConfig and Reset
|
||||
* SetOption11 (0) - If set perform single press action on double press and reverse (on two relay devices only)
|
||||
* SetOption13 (0) - If set act on single press only
|
||||
* SetOption32 (40) - Max button hold time in Seconds
|
||||
* SetOption40 (0) - Number of 0.1 seconds until hold is discarded if SetOption1 1 and SetOption13 0
|
||||
* SetOption73 (0) - Decouple button from relay and send just mqtt topic
|
||||
\*********************************************************************************************/
|
||||
|
||||
@ -118,11 +112,7 @@ void ButtonHandler(void)
|
||||
uint8_t hold_time_extent = IMMINENT_RESET_FACTOR; // Extent hold time factor in case of iminnent Reset command
|
||||
uint16_t loops_per_second = 1000 / Settings.button_debounce; // ButtonDebounce (50)
|
||||
char scmnd[20];
|
||||
char scommand[CMDSZ];
|
||||
char stopic[TOPSZ];
|
||||
|
||||
// uint8_t maxdev = (devices_present > MAX_KEYS) ? MAX_KEYS : devices_present;
|
||||
// for (uint32_t button_index = 0; button_index < maxdev; button_index++) {
|
||||
for (uint32_t button_index = 0; button_index < MAX_KEYS; button_index++) {
|
||||
uint8_t button = NOT_PRESSED;
|
||||
uint8_t button_present = 0;
|
||||
@ -179,23 +169,28 @@ void ButtonHandler(void)
|
||||
if (!Button.hold_timer[button_index]) { button_pressed = true; } // Do not allow within 1 second
|
||||
}
|
||||
if (button_pressed) {
|
||||
if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
|
||||
|
||||
if (!Settings.flag3.mqtt_buttons) {
|
||||
if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
|
||||
}
|
||||
} else {
|
||||
MqttButtonTopic(button_index +1, 1, 0); // SetOption73 (0) - Decouple button from relay and send just mqtt topic
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ESP8266
|
||||
else {
|
||||
|
||||
if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) {
|
||||
|
||||
if (Settings.flag.button_single && !Settings.flag3.mqtt_buttons) { // SetOption13 (0) - Allow only single button press for immediate action, SetOption73 (0) - Decouple button from relay and send just mqtt topic
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1);
|
||||
if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
|
||||
if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action, SetOption73 (0) - Decouple button from relay and send just mqtt topic
|
||||
if (!Settings.flag3.mqtt_buttons) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1);
|
||||
if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||
ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
|
||||
}
|
||||
} else {
|
||||
MqttButtonTopic(button_index +1, 1, 0); // SetOption73 (0) - Decouple button from relay and send just mqtt topic
|
||||
}
|
||||
|
||||
} else {
|
||||
Button.press_counter[button_index] = (Button.window_timer[button_index]) ? Button.press_counter[button_index] +1 : 1;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_MULTI_PRESS " %d"), button_index +1, Button.press_counter[button_index]);
|
||||
@ -217,27 +212,28 @@ void ButtonHandler(void)
|
||||
if (Button.hold_timer[button_index] == loops_per_second * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button hold
|
||||
Button.press_counter[button_index] = 0;
|
||||
if (Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic
|
||||
snprintf_P(scommand, sizeof(scommand), PSTR("BUTTON%d"), button_index +1);
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
||||
Response_P(S_JSON_COMMAND_SVALUE, "ACTION", GetStateText(3));
|
||||
MqttPublish(stopic);
|
||||
MqttButtonTopic(button_index +1, 3, 1);
|
||||
} else {
|
||||
SendKey(KEY_BUTTON, button_index +1, POWER_HOLD); // Execute Hold command via MQTT if ButtonTopic is set
|
||||
}
|
||||
SendKey(KEY_BUTTON, button_index +1, POWER_HOLD); // Execute Hold command via MQTT if ButtonTopic is set
|
||||
} else {
|
||||
if (Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer
|
||||
Button.press_counter[button_index] = 0;
|
||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1"));
|
||||
ExecuteCommand(scmnd, SRC_BUTTON);
|
||||
if (!Settings.flag.button_restrict) {
|
||||
if ((Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10)) { // SetOption32 (40) - Button held for factor times longer
|
||||
Button.press_counter[button_index] = 0;
|
||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1"));
|
||||
ExecuteCommand(scmnd, SRC_BUTTON);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Settings.flag.button_single) { // SetOption13 (0) - Allow multi-press
|
||||
if (!Settings.flag.button_single) { // SetOption13 (0) - Allow multi-press
|
||||
if (Button.window_timer[button_index]) {
|
||||
Button.window_timer[button_index]--;
|
||||
} else {
|
||||
if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < MAX_BUTTON_COMMANDS_V2 +6)) {
|
||||
if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < 7)) {
|
||||
|
||||
bool single_press = false;
|
||||
if (Button.press_counter[button_index] < 3) { // Single or Double press
|
||||
#ifdef ESP8266
|
||||
@ -251,10 +247,6 @@ void ButtonHandler(void)
|
||||
if (Settings.flag.button_swap) { // SetOption11 (0)
|
||||
Button.press_counter[button_index] = (single_press) ? 1 : 2;
|
||||
}
|
||||
// } else {
|
||||
// if (!Settings.flag3.mqtt_buttons && button_index != 0) {
|
||||
// Button.press_counter[button_index] = 1;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -273,7 +265,7 @@ void ButtonHandler(void)
|
||||
ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON);
|
||||
} else {
|
||||
SendKey(KEY_BUTTON, button_index +1, Button.press_counter[button_index] +9); // 2,3,4 and 5 press send just the key value (11,12,13 and 14) for rules
|
||||
if (0 == button_index) { // First button can toggle up to 4 relays if present
|
||||
if (0 == button_index) { // BUTTON1 can toggle up to 5 relays if present. If a relay is not present will send out the key value (2,11,12,13 and 14) for rules
|
||||
if ((Button.press_counter[button_index] > 1 && pin[GPIO_REL1 + Button.press_counter[button_index]-1] < 99) && Button.press_counter[button_index] <= MAX_RELAY_BUTTON1) {
|
||||
ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: Relay%d found on GPIO%d"), Button.press_counter[button_index], pin[GPIO_REL1 + Button.press_counter[button_index]-1]);
|
||||
@ -281,21 +273,16 @@ void ButtonHandler(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // 6 - 8 press are used to send commands
|
||||
GetTextIndexed(scmnd, sizeof(scmnd), Button.press_counter[button_index] -6, kCommands);
|
||||
|
||||
} else { // 6 press start wificonfig 2
|
||||
if (!Settings.flag.button_restrict) {
|
||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_WIFICONFIG " 2"));
|
||||
ExecuteCommand(scmnd, SRC_BUTTON);
|
||||
}
|
||||
}
|
||||
if (Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic
|
||||
if (Button.press_counter[button_index] >= 1 && Button.press_counter[button_index] <= 5) {
|
||||
char mqttstate[7];
|
||||
|
||||
GetTextIndexed(mqttstate, sizeof(mqttstate), Button.press_counter[button_index], kMultiPress);
|
||||
SendKey(KEY_BUTTON, button_index +1, Button.press_counter[button_index] +9);
|
||||
snprintf_P(scommand, sizeof(scommand), PSTR("BUTTON%d"), button_index +1);
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
||||
Response_P(S_JSON_COMMAND_SVALUE, "ACTION", mqttstate);
|
||||
MqttPublish(stopic);
|
||||
|
||||
MqttButtonTopic(button_index +1, Button.press_counter[button_index], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -306,12 +293,28 @@ void ButtonHandler(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Button.last_state[button_index] = button;
|
||||
}
|
||||
}
|
||||
|
||||
void MqttButtonTopic(uint8_t button_id, uint8_t action, uint8_t hold)
|
||||
{
|
||||
char scommand[CMDSZ];
|
||||
char stopic[TOPSZ];
|
||||
char mqttstate[7];
|
||||
|
||||
GetTextIndexed(mqttstate, sizeof(mqttstate), action, kMultiPress);
|
||||
|
||||
SendKey(KEY_BUTTON, button_id, (hold) ? 3 : action +9);
|
||||
snprintf_P(scommand, sizeof(scommand), PSTR("BUTTON%d"), button_id);
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
|
||||
Response_P(S_JSON_COMMAND_SVALUE, "ACTION", (hold) ? SettingsText(SET_STATE_TXT4) : mqttstate);
|
||||
MqttPublish(stopic);
|
||||
}
|
||||
|
||||
void ButtonLoop(void)
|
||||
{
|
||||
if (Button.present) {
|
||||
|
@ -36,7 +36,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
D_CMND_DEVGROUP_SEND "|"
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
D_CMND_DEVGROUP_SHARE "|"
|
||||
D_CMND_DEVGROUP_SHARE "|" D_CMND_DEVGROUPSTATUS "|"
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
D_CMND_SENSOR "|" D_CMND_DRIVER;
|
||||
|
||||
@ -59,7 +59,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
&CmndDevGroupSend,
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
&CmndDevGroupShare,
|
||||
&CmndDevGroupShare, &CmndDevGroupStatus,
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
&CmndSensor, &CmndDriver };
|
||||
|
||||
@ -413,20 +413,34 @@ void CmndStatus(void)
|
||||
if ((0 == payload) || (1 == payload)) {
|
||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_SERIALCONFIG "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\""
|
||||
D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\""
|
||||
D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"BCResetTime\":\"%s\",\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
||||
D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"BCResetTime\":\"%s\",\"" D_JSON_SAVECOUNT "\":%d"
|
||||
#ifdef ESP8266
|
||||
",\"" D_JSON_SAVEADDRESS "\":\"%X\""
|
||||
#endif
|
||||
"}}"),
|
||||
Settings.baudrate * 300, GetSerialConfig().c_str(), SettingsText(SET_MQTT_GRP_TOPIC), SettingsText(SET_OTAURL),
|
||||
GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep,
|
||||
Settings.cfg_holder, Settings.bootcount, GetDateAndTime(DT_BOOTCOUNT).c_str(), Settings.save_flag, GetSettingsAddress());
|
||||
Settings.cfg_holder, Settings.bootcount, GetDateAndTime(DT_BOOTCOUNT).c_str(), Settings.save_flag
|
||||
#ifdef ESP8266
|
||||
, GetSettingsAddress()
|
||||
#endif
|
||||
);
|
||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
||||
}
|
||||
|
||||
if ((0 == payload) || (2 == payload)) {
|
||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\",\""
|
||||
D_JSON_BOOTVERSION "\":%d,\"" D_JSON_COREVERSION "\":\"" ARDUINO_CORE_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\","
|
||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\""
|
||||
#ifdef ESP8266
|
||||
",\"" D_JSON_BOOTVERSION "\":%d"
|
||||
#endif
|
||||
",\"" D_JSON_COREVERSION "\":\"" ARDUINO_CORE_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\","
|
||||
"\"Hardware\":\"%s\""
|
||||
"%s}}"),
|
||||
my_version, my_image, GetBuildDateAndTime().c_str(),
|
||||
ESP_getBootVersion(), ESP.getSdkVersion(),
|
||||
my_version, my_image, GetBuildDateAndTime().c_str()
|
||||
#ifdef ESP8266
|
||||
, ESP.getBootVersion()
|
||||
#endif
|
||||
, ESP.getSdkVersion(),
|
||||
GetDeviceHardware().c_str(),
|
||||
GetStatistics().c_str());
|
||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2"));
|
||||
@ -445,10 +459,18 @@ void CmndStatus(void)
|
||||
|
||||
if ((0 == payload) || (4 == payload)) {
|
||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_JSON_PROGRAMSIZE "\":%d,\"" D_JSON_FREEMEMORY "\":%d,\"" D_JSON_HEAPSIZE "\":%d,\""
|
||||
D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d,\"" D_JSON_FLASHCHIPID "\":\"%06X\",\"" D_JSON_FLASHMODE "\":%d,\""
|
||||
D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d"
|
||||
#ifdef ESP8266
|
||||
",\"" D_JSON_FLASHCHIPID "\":\"%06X\""
|
||||
#endif
|
||||
",\"" D_JSON_FLASHMODE "\":%d,\""
|
||||
D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"),
|
||||
ESP_getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024,
|
||||
ESP.getFlashChipSize()/1024, ESP_getFlashChipRealSize()/1024, ESP_getFlashChipId(), ESP.getFlashChipMode(),
|
||||
ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024
|
||||
#ifdef ESP8266
|
||||
, ESP.getFlashChipId()
|
||||
#endif
|
||||
, ESP.getFlashChipMode(),
|
||||
LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6);
|
||||
XsnsDriverState();
|
||||
ResponseAppend_P(PSTR(",\"Sensors\":"));
|
||||
@ -1114,13 +1136,8 @@ void CmndTemplate(void)
|
||||
SettingsUpdateText(SET_TEMPLATE_NAME, "Merged");
|
||||
uint32_t j = 0;
|
||||
for (uint32_t i = 0; i < sizeof(mycfgio); i++) {
|
||||
#ifdef ESP8266
|
||||
if (6 == i) { j = 9; }
|
||||
if (8 == i) { j = 12; }
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
if (6 == i) { j = 12; }
|
||||
#endif // ESP32
|
||||
if (my_module.io[j] > GPIO_NONE) {
|
||||
Settings.user_template.gp.io[i] = my_module.io[j];
|
||||
}
|
||||
@ -1793,6 +1810,11 @@ void CmndDevGroupShare(void)
|
||||
Settings.device_group_share_out = parm[1];
|
||||
Response_P(PSTR("{\"" D_CMND_DEVGROUP_SHARE "\":{\"In\":\"%X\",\"Out\":\"%X\"}}"), Settings.device_group_share_in, Settings.device_group_share_out);
|
||||
}
|
||||
|
||||
void CmndDevGroupStatus(void)
|
||||
{
|
||||
DeviceGroupStatus((XdrvMailbox.usridx ? XdrvMailbox.index - 1 : 0));
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
||||
void CmndSensor(void)
|
||||
|
@ -34,6 +34,7 @@ struct device_group_member {
|
||||
IPAddress ip_address;
|
||||
uint16_t received_sequence;
|
||||
uint16_t acked_sequence;
|
||||
uint32_t unicast_count;
|
||||
};
|
||||
|
||||
struct device_group {
|
||||
@ -48,7 +49,6 @@ struct device_group {
|
||||
bool local;
|
||||
char group_name[TOPSZ];
|
||||
char message[128];
|
||||
uint8_t group_member_count;
|
||||
struct device_group_member * device_group_members;
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
uint8_t values_8bit[DGR_ITEM_LAST_8BIT];
|
||||
@ -77,7 +77,7 @@ void DeviceGroupsInit(void)
|
||||
// Initialize the device information for each device group.
|
||||
device_groups = (struct device_group *)calloc(device_group_count, sizeof(struct device_group));
|
||||
if (device_groups == nullptr) {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating %u-element device group array"), device_group_count);
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error allocating %u-element device group array"), device_group_count);
|
||||
device_groups_initialization_failed = true;
|
||||
return;
|
||||
}
|
||||
@ -155,6 +155,9 @@ bool DeviceGroupItemShared(bool incoming, uint8_t item)
|
||||
case DGR_ITEM_BRI_PRESET_HIGH:
|
||||
mask = DGR_SHARE_DIMMER_SETTINGS;
|
||||
break;
|
||||
case DGR_ITEM_EVENT:
|
||||
mask = DGR_SHARE_EVENT;
|
||||
break;
|
||||
}
|
||||
return (!mask || ((incoming ? Settings.device_group_share_in : Settings.device_group_share_out) & mask));
|
||||
}
|
||||
@ -169,7 +172,7 @@ void SendDeviceGroupPacket(IPAddress ip, char * packet, int len, const char * la
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error sending %s packet"), label);
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error sending %s packet"), label);
|
||||
}
|
||||
|
||||
void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType message_type, ...)
|
||||
@ -184,7 +187,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
if (processing_remote_device_message && message_type != DGR_MSGTYPE_UPDATE_COMMAND) return;
|
||||
|
||||
// Get a pointer to the device information for this device.
|
||||
device_group * device_group = &device_groups[device_group_index];
|
||||
struct device_group * device_group = &device_groups[device_group_index];
|
||||
|
||||
// If we're still sending initial status requests, ignore this request.
|
||||
if (device_group->initial_status_requests_remaining) return;
|
||||
@ -225,24 +228,29 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
|
||||
else {
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
bool escaped;
|
||||
bool use_command;
|
||||
char chr;
|
||||
char oper;
|
||||
uint32_t old_value;
|
||||
char * delim_ptr;
|
||||
char * out_ptr;
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
struct item {
|
||||
uint8_t item;
|
||||
uint32_t value;
|
||||
void * value_ptr;
|
||||
} item_array[32];
|
||||
bool shared;
|
||||
uint8_t item;
|
||||
uint32_t value;
|
||||
char * value_ptr;
|
||||
struct item * item_ptr;
|
||||
va_list ap;
|
||||
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Building device group %s packet"), device_group->group_name);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
use_command = (message_type == DGR_MSGTYPE_UPDATE_COMMAND);
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
value = 0;
|
||||
if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME)
|
||||
value |= DGR_FLAG_MORE_TO_COME;
|
||||
@ -253,73 +261,96 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
message_ptr = BeginDeviceGroupMessage(device_group, value, building_status_message || message_type == DGR_MSGTYP_PARTIAL_UPDATE);
|
||||
|
||||
// Build an array of all the items and values in this update.
|
||||
memset(item_array, 0, sizeof(item_array));
|
||||
item_ptr = item_array;
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
use_command = (message_type == DGR_MSGTYPE_UPDATE_COMMAND);
|
||||
if (use_command) {
|
||||
value_ptr = XdrvMailbox.data;
|
||||
while ((item = strtoul(value_ptr, &value_ptr, 0))) {
|
||||
item_ptr->item = item;
|
||||
if (*value_ptr == '=') {
|
||||
value_ptr++;
|
||||
if (item <= DGR_ITEM_MAX_32BIT) {
|
||||
oper = 0;
|
||||
if (*value_ptr == '@') {
|
||||
oper = value_ptr[1];
|
||||
value_ptr += 2;
|
||||
}
|
||||
value = strtoul(value_ptr, &value_ptr, 0);
|
||||
if (oper) {
|
||||
old_value = (item <= DGR_ITEM_MAX_8BIT ? device_group->values_8bit[item] : (item <= DGR_ITEM_MAX_16BIT ? device_group->values_16bit[item - DGR_ITEM_MAX_8BIT - 1] : device_group->values_32bit[item - DGR_ITEM_MAX_16BIT - 1]));
|
||||
value = (oper == '+' ? old_value + value : (oper == '-' ? old_value - value : (oper == '^' ? old_value ^ (value ? value : 0xffffffff) : old_value)));
|
||||
}
|
||||
item_ptr->value = value;
|
||||
}
|
||||
else if (item <= DGR_ITEM_MAX_STRING) {
|
||||
item_ptr->value_ptr = out_ptr = value_ptr;
|
||||
escaped = false;
|
||||
while ((chr = *value_ptr++)) {
|
||||
if (chr == ' ' && !escaped) break;
|
||||
if (!(escaped = (chr == '\\' && !escaped))) *out_ptr++ = chr;
|
||||
}
|
||||
*out_ptr = 0;
|
||||
}
|
||||
else {
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
item_ptr->value_ptr = out_ptr = value_ptr;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
*out_ptr = strtoul(value_ptr, &value_ptr, 0);
|
||||
if (*value_ptr == ',') value_ptr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
item_ptr++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
va_start(ap, message_type);
|
||||
while ((item = va_arg(ap, int))) {
|
||||
item_ptr->item = item;
|
||||
if (item <= DGR_ITEM_MAX_32BIT)
|
||||
item_ptr->value = va_arg(ap, int);
|
||||
else if (item <= DGR_ITEM_MAX_STRING)
|
||||
item_ptr->value_ptr = va_arg(ap, char *);
|
||||
else {
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
item_ptr->value_ptr = va_arg(ap, uint8_t *);
|
||||
break;
|
||||
}
|
||||
}
|
||||
item_ptr++;
|
||||
}
|
||||
va_end(ap);
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
|
||||
// If we're still building this update or all group members haven't acknowledged the previous
|
||||
// update yet, update the message to include these new updates. First we need to rebuild the
|
||||
// previous update message to remove any items and their values that are included in this new
|
||||
// update.
|
||||
if (device_group->message_length) {
|
||||
uint8_t item_array[32];
|
||||
int item_index = 0;
|
||||
int kept_item_count = 0;
|
||||
|
||||
// Build an array of all the items in this new update.
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
if (use_command)
|
||||
value_ptr = XdrvMailbox.data;
|
||||
else
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
va_start(ap, message_type);
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
while (use_command ? (item = strtoul(value_ptr, &delim_ptr, 0)) : (item = va_arg(ap, int))) {
|
||||
#else // USE_DEVICE_GROUPS_SEND
|
||||
while ((item = va_arg(ap, int))) {
|
||||
#endif // !USE_DEVICE_GROUPS_SEND
|
||||
item_array[item_index++] = item;
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
if (use_command) {
|
||||
if (!*delim_ptr) break;
|
||||
if (*delim_ptr == '=') {
|
||||
delim_ptr = strchr(delim_ptr, ' ');
|
||||
if (!delim_ptr) break;
|
||||
}
|
||||
value_ptr = delim_ptr + 1;
|
||||
}
|
||||
else {
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
if (item <= DGR_ITEM_MAX_32BIT)
|
||||
va_arg(ap, int);
|
||||
else if (item <= DGR_ITEM_MAX_STRING)
|
||||
va_arg(ap, char *);
|
||||
else {
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
va_arg(ap, uint8_t *);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
}
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
if (!use_command) va_end(ap);
|
||||
#else // USE_DEVICE_GROUPS_SEND
|
||||
va_end(ap);
|
||||
#endif // !USE_DEVICE_GROUPS_SEND
|
||||
item_array[item_index] = 0;
|
||||
|
||||
// Rebuild the previous update message, removing any items whose values are included in this
|
||||
// new update.
|
||||
char * previous_message_ptr = message_ptr;
|
||||
while (item = *previous_message_ptr++) {
|
||||
|
||||
// Search for this item in the new update.
|
||||
for (item_index = 0; item_array[item_index]; item_index++) {
|
||||
if (item_array[item_index] == item) break;
|
||||
for (item_ptr = item_array; item_ptr->item; item_ptr++) {
|
||||
if (item_ptr->item == item) break;
|
||||
}
|
||||
|
||||
// If this item was found in the new update skip over it and it's value.
|
||||
if (item_array[item_index]) {
|
||||
if (item_ptr->item) {
|
||||
if (item <= DGR_ITEM_MAX_32BIT) {
|
||||
previous_message_ptr++;
|
||||
if (item > DGR_ITEM_MAX_8BIT) {
|
||||
@ -330,8 +361,9 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (item <= DGR_ITEM_MAX_STRING)
|
||||
previous_message_ptr += *previous_message_ptr++;
|
||||
else if (item <= DGR_ITEM_MAX_STRING) {
|
||||
previous_message_ptr += strlen(previous_message_ptr) + 1;
|
||||
}
|
||||
else {
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
@ -355,7 +387,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
}
|
||||
}
|
||||
else if (item <= DGR_ITEM_MAX_STRING) {
|
||||
*message_ptr++ = value = *previous_message_ptr++;
|
||||
value = strlen(previous_message_ptr) + 1;
|
||||
memmove(message_ptr, previous_message_ptr, value);
|
||||
previous_message_ptr += value;
|
||||
message_ptr += value;
|
||||
@ -378,58 +410,20 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
}
|
||||
|
||||
// Itertate through the passed items adding them and their values to the message.
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
if (use_command)
|
||||
value_ptr = XdrvMailbox.data;
|
||||
else
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
va_start(ap, message_type);
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
while (use_command ? (item = strtoul(value_ptr, &delim_ptr, 0)) : (item = va_arg(ap, int))) {
|
||||
#else // !USE_DEVICE_GROUPS_SEND
|
||||
while ((item = va_arg(ap, int))) {
|
||||
#endif // !USE_DEVICE_GROUPS_SEND
|
||||
for (item_ptr = item_array; (item = item_ptr->item); item_ptr++) {
|
||||
|
||||
// Find out if this item is shared with the group and add the item code to the message if yes.
|
||||
// If this item is shared with the group add it to the message.
|
||||
shared = true;
|
||||
if (!device_group_index) shared = DeviceGroupItemShared(false, item);
|
||||
if (shared) *message_ptr++ = item;
|
||||
if (shared) {
|
||||
*message_ptr++ = item;
|
||||
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
// If we're processing a command, get a pointer to the value if one was specified.
|
||||
if (use_command) value_ptr = (*delim_ptr == '=' ? delim_ptr + 1 : nullptr);
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
|
||||
// For numeric items, get the specified value.
|
||||
if (item <= DGR_ITEM_MAX_32BIT) {
|
||||
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
// If we're processing a command, get the final value after processing any specified
|
||||
// operators.
|
||||
if (use_command) {
|
||||
value = 0;
|
||||
if (value_ptr) {
|
||||
oper = 0;
|
||||
if (*value_ptr == '@') {
|
||||
oper = value_ptr[1];
|
||||
value_ptr += 2;
|
||||
}
|
||||
value = strtoul(value_ptr, nullptr, 0);
|
||||
if (oper) {
|
||||
old_value = (item <= DGR_ITEM_MAX_8BIT ? device_group->values_8bit[item] : (item <= DGR_ITEM_MAX_16BIT ? device_group->values_16bit[item - DGR_ITEM_MAX_8BIT - 1] : device_group->values_32bit[item - DGR_ITEM_MAX_16BIT - 1]));
|
||||
value = (oper == '+' ? old_value + value : (oper == '-' ? old_value - value : (oper == '^' ? old_value ^ (value ? value : 0xffffffff) : old_value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
value = va_arg(ap, int);
|
||||
|
||||
// If the item is shared, add it to the message.
|
||||
if (shared) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%u"), item, value);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
// For integer items, add the value to the message.
|
||||
if (item <= DGR_ITEM_MAX_32BIT) {
|
||||
value = item_ptr->value;
|
||||
//#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(">%u=%u"), item, value);
|
||||
//#endif // DEVICE_GROUPS_DEBUG
|
||||
*message_ptr++ = value & 0xff;
|
||||
if (item > DGR_ITEM_MAX_8BIT) {
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
@ -469,77 +463,36 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
}
|
||||
}
|
||||
|
||||
// For string items, add the string to the message prefixed by the length.
|
||||
else if (item <= DGR_ITEM_MAX_STRING) {
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
if (!use_command)
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
value_ptr = va_arg(ap, char *);
|
||||
if (shared) {
|
||||
value = (value_ptr ? strlen((const char *)value_ptr) : 0);
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%s"), item, value_ptr);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
*message_ptr++ = value;
|
||||
memcpy(message_ptr, value_ptr, value);
|
||||
message_ptr += value;
|
||||
// For string items, add the null-terminated string to the message.
|
||||
else if (item <= DGR_ITEM_MAX_STRING) {
|
||||
if (item_ptr->value_ptr) {
|
||||
value = strlen((const char *)item_ptr->value_ptr);
|
||||
memcpy(message_ptr, item_ptr->value_ptr, value);
|
||||
message_ptr += value;
|
||||
}
|
||||
*message_ptr++ = 0;
|
||||
//#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(">%u='%s'"), item, item_ptr->value_ptr);
|
||||
//#endif // DEVICE_GROUPS_DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
// For special items, handle them individually.
|
||||
else {
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
if (use_command) {
|
||||
if (shared) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
value = 0;
|
||||
if (value_ptr) {
|
||||
value = strtoul(value_ptr, &value_ptr, 0);
|
||||
value_ptr = (*value_ptr == ',' ? value_ptr + 1 : nullptr);
|
||||
}
|
||||
*message_ptr++ = value;
|
||||
}
|
||||
// For special items, handle them individually.
|
||||
else {
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
value_ptr = (char *)item_ptr->value_ptr;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
*message_ptr++ = (value_ptr ? *value_ptr++ : 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
value_ptr = va_arg(ap, char *);
|
||||
if (shared) {
|
||||
memmove(message_ptr, value_ptr, 5);
|
||||
message_ptr += 5;
|
||||
}
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
if (shared) AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%u,%u,%u,%u,%u"), item, *(message_ptr - 5), *(message_ptr - 4), *(message_ptr - 3), *(message_ptr - 2), *(message_ptr - 1));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
break;
|
||||
//#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(">%u=%u,%u,%u,%u,%u"), item, *(message_ptr - 5), *(message_ptr - 4), *(message_ptr - 3), *(message_ptr - 2), *(message_ptr - 1));
|
||||
//#endif // DEVICE_GROUPS_DEBUG
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
// If we're processing a command, advance to the next item. If there are no more, break out of
|
||||
// the loop.
|
||||
if (use_command) {
|
||||
if (!*delim_ptr) break;
|
||||
if (*delim_ptr == '=') {
|
||||
delim_ptr = strchr(delim_ptr, ' ');
|
||||
if (!delim_ptr) break;
|
||||
}
|
||||
value_ptr = delim_ptr + 1;
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
}
|
||||
#ifdef USE_DEVICE_GROUPS_SEND
|
||||
if (!use_command) va_end(ap);
|
||||
#else // USE_DEVICE_GROUPS_SEND
|
||||
va_end(ap);
|
||||
#endif // !USE_DEVICE_GROUPS_SEND
|
||||
|
||||
// Add the EOL item code and calculate the message length.
|
||||
*message_ptr++ = 0;
|
||||
@ -551,7 +504,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
|
||||
|
||||
// Multicast the packet.
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Multicast"));
|
||||
|
||||
@ -598,12 +551,10 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
if (!device_group_member) {
|
||||
device_group_member = (struct device_group_member *)calloc(1, sizeof(struct device_group_member));
|
||||
if (device_group_member == nullptr) {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating device group member block"));
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error allocating device group member block"));
|
||||
return;
|
||||
}
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: adding member %s (%p)"), IPAddressToString(remote_ip), device_group_member);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Adding member %s"), IPAddressToString(remote_ip));
|
||||
device_group_member->ip_address = remote_ip;
|
||||
*flink = device_group_member;
|
||||
break;
|
||||
@ -717,10 +668,11 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
case DGR_ITEM_BRI_PRESET_HIGH:
|
||||
case DGR_ITEM_BRI_POWER_ON:
|
||||
case DGR_ITEM_POWER:
|
||||
case DGR_ITEM_EVENT:
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
break;
|
||||
default:
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: ********** invalid item=%u received from device group %s member %s"), item, device_group->group_name, IPAddressToString(remote_ip));
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: ********** Invalid item=%u received from device group %s member %s"), item, device_group->group_name, IPAddressToString(remote_ip));
|
||||
}
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
|
||||
@ -748,27 +700,27 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS_SEND
|
||||
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<item=%u, value=%u"), item, value);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
//#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("<%u=%u"), item, value);
|
||||
//#endif // DEVICE_GROUPS_DEBUG
|
||||
XdrvMailbox.payload = value;
|
||||
}
|
||||
else if (item <= DGR_ITEM_MAX_STRING) {
|
||||
value = *message_ptr++;
|
||||
value = strlen(message_ptr);
|
||||
if (value >= packet_length - (message_ptr - packet)) goto badmsg; // Malformed message
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<item=%u, value=%.*s"), item, value, message_ptr);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
//#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("<%u='%s'"), item, message_ptr);
|
||||
//#endif // DEVICE_GROUPS_DEBUG
|
||||
XdrvMailbox.data_len = value;
|
||||
XdrvMailbox.data = message_ptr;
|
||||
message_ptr += value;
|
||||
message_ptr += value + 1;
|
||||
}
|
||||
else {
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<item=%u, value=%u,%u,%u,%u,%u"), item, *message_ptr, *(message_ptr + 1), *(message_ptr + 2), *(message_ptr + 3), *(message_ptr + 4));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
//#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("<%u=%u,%u,%u,%u,%u"), item, *message_ptr, *(message_ptr + 1), *(message_ptr + 2), *(message_ptr + 3), *(message_ptr + 4));
|
||||
//#endif // DEVICE_GROUPS_DEBUG
|
||||
XdrvMailbox.data = message_ptr;
|
||||
message_ptr += 5;
|
||||
break;
|
||||
@ -787,6 +739,9 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (item == DGR_ITEM_EVENT) {
|
||||
CmndEvent();
|
||||
}
|
||||
XdrvCall(FUNC_DEVICE_GROUP_ITEM);
|
||||
}
|
||||
}
|
||||
@ -802,13 +757,28 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
return;
|
||||
|
||||
badmsg:
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: malformed message received from %s"), IPAddressToString(remote_ip));
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Malformed message received from %s"), IPAddressToString(remote_ip));
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("packet_length=%u, offset=%u"), packet_length, message_ptr - packet);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
processing_remote_device_message = false;
|
||||
}
|
||||
|
||||
void DeviceGroupStatus(uint8_t device_group_index)
|
||||
{
|
||||
if (Settings.flag4.device_groups_enabled && device_group_index < device_group_count) {
|
||||
char buffer[1024];
|
||||
int member_count = 0;
|
||||
struct device_group * device_group = &device_groups[device_group_index];
|
||||
buffer[0] = buffer[1] = 0;
|
||||
for (struct device_group_member * device_group_member = device_group->device_group_members; device_group_member; device_group_member = device_group_member->flink) {
|
||||
snprintf(buffer, sizeof(buffer), PSTR("%s,{\"IPAddress\":\"%s\",\"ResendCount\":%u,\"LastRcvdSeq\":%u,\"LastAckedSeq\":%u}"), buffer, IPAddressToString(device_group_member->ip_address), device_group_member->unicast_count, device_group_member->received_sequence, device_group_member->acked_sequence);
|
||||
member_count++;
|
||||
}
|
||||
Response_P(PSTR("{\"" D_CMND_DEVGROUPSTATUS "\":{\"Index\":%u,\"GroupName\":\"%s\",\"MessageSeq\":%u,\"MemberCount\":%d,\"Members\":[%s]}"), device_group_index, device_group->group_name, outgoing_sequence, member_count, &buffer[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceGroupsLoop(void)
|
||||
{
|
||||
if (!Settings.flag4.device_groups_enabled) return;
|
||||
@ -822,16 +792,16 @@ void DeviceGroupsLoop(void)
|
||||
if (!device_groups_initialized) DeviceGroupsInit();
|
||||
if (device_groups_initialization_failed) return;
|
||||
|
||||
// Load the status request message for all device groups. This message will be multicast 5
|
||||
// times.
|
||||
// Load the status request message for all device groups. This message will be multicast 10
|
||||
// times at 200ms intervals.
|
||||
next_check_time = now + 3000;
|
||||
for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++) {
|
||||
device_group * device_group = &device_groups[device_group_index];
|
||||
device_group->message_length = BeginDeviceGroupMessage(device_group, DGR_FLAG_RESET | DGR_FLAG_STATUS_REQUEST) - device_group->message;
|
||||
device_group->initial_status_requests_remaining = 5;
|
||||
device_group->initial_status_requests_remaining = 10;
|
||||
device_group->next_ack_check_time = next_check_time;
|
||||
}
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: (Re)discovering device groups"));
|
||||
}
|
||||
|
||||
if (device_groups_initialization_failed) return;
|
||||
@ -856,15 +826,15 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
|
||||
if (device_group->initial_status_requests_remaining) {
|
||||
if (--device_group->initial_status_requests_remaining) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending initial status request for group %s"), device_group->group_name);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending initial status request for group %s"), device_group->group_name);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Initial"));
|
||||
device_group->message[device_group->message_header_length + 2] = DGR_FLAG_STATUS_REQUEST; // The reset flag is on only for the first packet - turn it off now
|
||||
device_group->next_ack_check_time = now + 200;
|
||||
}
|
||||
|
||||
// If we've sent the initial status request message 5 times, send our status to all
|
||||
// the members.
|
||||
// If we've sent the initial status request message the set number of times, send our
|
||||
// status to all the members.
|
||||
else {
|
||||
device_group->next_ack_check_time = 0;
|
||||
_SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_FULL_STATUS);
|
||||
@ -874,7 +844,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
|
||||
// If we're done initializing, iterate through the group memebers, ...
|
||||
else {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: checking for ack's"));
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Checking for ack's"));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
bool acked = true;
|
||||
struct device_group_member ** flink = &device_group->device_group_members;
|
||||
@ -887,9 +857,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
|
||||
// If we haven't receive an ack from this member in DGR_MEMBER_TIMEOUT ms, assume
|
||||
// they're offline and remove them from the group.
|
||||
if (device_group->member_timeout_time < now) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: removing member %s (%p)"), IPAddressToString(device_group_member->ip_address), device_group_member);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Removing member %s"), IPAddressToString(device_group_member->ip_address));
|
||||
*flink = device_group_member->flink;
|
||||
free(device_group_member);
|
||||
}
|
||||
@ -897,9 +865,10 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
|
||||
// Otherwise, unicast the last message directly to this member.
|
||||
else {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via unicast to %s, sequence %u, last message acked=%u"), device_group->message_length, device_group->group_name, IPAddressToString(device_group_member->ip_address), outgoing_sequence, device_group_member->acked_sequence);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending %u-byte device group %s packet via unicast to %s, sequence %u, last message acked=%u"), device_group->message_length, device_group->group_name, IPAddressToString(device_group_member->ip_address), outgoing_sequence, device_group_member->acked_sequence);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
SendDeviceGroupPacket(device_group_member->ip_address, device_group->message, device_group->message_length, PSTR("Unicast"));
|
||||
device_group_member->unicast_count++;
|
||||
acked = false;
|
||||
flink = &device_group_member->flink;
|
||||
}
|
||||
@ -940,7 +909,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
if (device_group->next_announcement_time <= now) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending device group %s announcement"), device_group->group_name);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending device group %s announcement"), device_group->group_name);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, PSTR("Announcement"));
|
||||
device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL + random(10000);
|
||||
|
@ -17,11 +17,86 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP8266 Support
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef ESP8266
|
||||
|
||||
extern "C" {
|
||||
extern struct rst_info resetInfo;
|
||||
}
|
||||
|
||||
uint32_t ESP_ResetInfoReason(void)
|
||||
{
|
||||
return resetInfo.reason;
|
||||
}
|
||||
|
||||
String ESP_getResetReason(void)
|
||||
{
|
||||
return ESP.getResetReason();
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipId(void)
|
||||
{
|
||||
return ESP.getChipId();
|
||||
}
|
||||
|
||||
uint32_t ESP_getSketchSize(void)
|
||||
{
|
||||
return ESP.getSketchSize();
|
||||
}
|
||||
|
||||
void ESP_Restart(void)
|
||||
{
|
||||
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
|
||||
ESP.reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP32 Support
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
#include <nvs.h>
|
||||
#include <rom/rtc.h>
|
||||
|
||||
void NvmLoad(const char *sNvsName, const char *sName, void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READONLY, &handle);
|
||||
size_t size = nSettingsLen;
|
||||
nvs_get_blob(handle, sName, pSettings, &size);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void NvmSave(const char *sNvsName, const char *sName, const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READWRITE, &handle);
|
||||
nvs_set_blob(handle, sName, pSettings, nSettingsLen);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void NvmErase(const char *sNvsName)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READWRITE, &handle);
|
||||
nvs_erase_all(handle);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void SettingsErase(uint8_t type)
|
||||
{
|
||||
if (1 == type) // SDK parameter area
|
||||
@ -34,75 +109,29 @@ void SettingsErase(uint8_t type)
|
||||
{
|
||||
}
|
||||
|
||||
noInterrupts();
|
||||
nvs_handle handle;
|
||||
nvs_open("main", NVS_READWRITE, &handle);
|
||||
nvs_erase_all(handle);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
NvmErase("main");
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " t=%d"), type);
|
||||
}
|
||||
|
||||
void SettingsLoad(const char *sNvsName, const char *sName, void *pSettings, unsigned nSettingsLen)
|
||||
void SettingsRead(void *data, size_t size)
|
||||
{
|
||||
noInterrupts();
|
||||
nvs_handle handle;
|
||||
size_t size;
|
||||
nvs_open(sNvsName, NVS_READONLY, &handle);
|
||||
size = nSettingsLen;
|
||||
nvs_get_blob(handle, sName, pSettings, &size);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
NvmLoad("main", "Settings", data, size);
|
||||
}
|
||||
|
||||
void SettingsSave(const char *sNvsName, const char *sName, const void *pSettings, unsigned nSettingsLen)
|
||||
void SettingsWrite(const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
nvs_handle handle;
|
||||
noInterrupts();
|
||||
nvs_open(sNvsName, NVS_READWRITE, &handle);
|
||||
nvs_set_blob(handle, sName, pSettings, nSettingsLen);
|
||||
nvs_commit(handle);
|
||||
nvs_close(handle);
|
||||
interrupts();
|
||||
NvmSave("main", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void ESP32_flashRead(uint32_t offset, uint32_t *data, size_t size)
|
||||
void QPCRead(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("main", "Settings", data, size);
|
||||
NvmLoad("qpc", "pcreg", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void ESP32_flashReadHeader(uint32_t offset, uint32_t *data, size_t size)
|
||||
void QPCWrite(const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("main", "SettingsH", data, size);
|
||||
}
|
||||
|
||||
void SettingsSaveMain(const void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsSave("main", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
/*
|
||||
void SettingsLoadMain(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("main", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void SettingsLoadMainH(void *pSettingsH, unsigned nSettingsLenH)
|
||||
{
|
||||
SettingsLoad("main", "SettingsH", pSettingsH, nSettingsLenH);
|
||||
}
|
||||
*/
|
||||
|
||||
void SettingsLoadUpg(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("upg", "Settings", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
void SettingsLoadUpgH(void *pSettings, unsigned nSettingsLen)
|
||||
{
|
||||
SettingsLoad("upg", "SettingsH", pSettings, nSettingsLen);
|
||||
NvmSave("qpc", "pcreg", pSettings, nSettingsLen);
|
||||
}
|
||||
|
||||
//
|
||||
@ -174,4 +203,82 @@ void CmndBlockedLoop(void)
|
||||
*/
|
||||
}
|
||||
|
||||
//
|
||||
// ESP32 specific
|
||||
//
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void DisableBrownout(void)
|
||||
{
|
||||
// https://github.com/espressif/arduino-esp32/issues/863#issuecomment-347179737
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector
|
||||
}
|
||||
|
||||
//
|
||||
// ESP32 Alternatives
|
||||
//
|
||||
|
||||
String ESP32GetResetReason(uint32_t cpu_no)
|
||||
{
|
||||
// tools\sdk\include\esp32\rom\rtc.h
|
||||
switch (rtc_get_reset_reason( (RESET_REASON) cpu_no)) {
|
||||
case POWERON_RESET : return F("Vbat power on reset"); // 1
|
||||
case SW_RESET : return F("Software reset digital core"); // 3
|
||||
case OWDT_RESET : return F("Legacy watch dog reset digital core"); // 4
|
||||
case DEEPSLEEP_RESET : return F("Deep Sleep reset digital core"); // 5
|
||||
case SDIO_RESET : return F("Reset by SLC module, reset digital core"); // 6
|
||||
case TG0WDT_SYS_RESET : return F("Timer Group0 Watch dog reset digital core"); // 7
|
||||
case TG1WDT_SYS_RESET : return F("Timer Group1 Watch dog reset digital core"); // 8
|
||||
case RTCWDT_SYS_RESET : return F("RTC Watch dog Reset digital core"); // 9
|
||||
case INTRUSION_RESET : return F("Instrusion tested to reset CPU"); // 10
|
||||
case TGWDT_CPU_RESET : return F("Time Group reset CPU"); // 11
|
||||
case SW_CPU_RESET : return F("Software reset CPU"); // 12
|
||||
case RTCWDT_CPU_RESET : return F("RTC Watch dog Reset CPU"); // 13
|
||||
case EXT_CPU_RESET : return F("or APP CPU, reseted by PRO CPU"); // 14
|
||||
case RTCWDT_BROWN_OUT_RESET : return F("Reset when the vdd voltage is not stable"); // 15
|
||||
case RTCWDT_RTC_RESET : return F("RTC Watch dog reset digital core and rtc module"); // 16
|
||||
default : return F("NO_MEAN"); // 0
|
||||
}
|
||||
}
|
||||
|
||||
String ESP_getResetReason(void)
|
||||
{
|
||||
return ESP32GetResetReason(0); // CPU 0
|
||||
}
|
||||
|
||||
uint32_t ESP_ResetInfoReason(void)
|
||||
{
|
||||
RESET_REASON reason = rtc_get_reset_reason(0);
|
||||
if (POWERON_RESET == reason) { return REASON_DEFAULT_RST; }
|
||||
if (SW_CPU_RESET == reason) { return REASON_SOFT_RESTART; }
|
||||
if (DEEPSLEEP_RESET == reason) { return REASON_DEEP_SLEEP_AWAKE; }
|
||||
if (SW_RESET == reason) { return REASON_EXT_SYS_RST; }
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipId(void)
|
||||
{
|
||||
uint32_t id = 0;
|
||||
for (uint32_t i = 0; i < 17; i = i +8) {
|
||||
id |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t ESP_getSketchSize(void)
|
||||
{
|
||||
static uint32_t sketchsize = 0;
|
||||
|
||||
if (!sketchsize) {
|
||||
sketchsize = ESP.getSketchSize(); // This takes almost 2 seconds on an ESP32
|
||||
}
|
||||
return sketchsize;
|
||||
}
|
||||
|
||||
void ESP_Restart(void)
|
||||
{
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
#endif // ESP32
|
||||
|
@ -371,13 +371,13 @@ void FLOG::stopRecording(void){
|
||||
*
|
||||
* @param size: size of the data entry/record in bytes, i.e. sizeof(myStruct)
|
||||
* @param sendHeader: should implement at least something like:
|
||||
* @example WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); // This is very likely unknown!!
|
||||
* WebServer->sendHeader(F("Content-Disposition"), F("attachment; filename=myfile.txt"));
|
||||
* @example Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN); // This is very likely unknown!!
|
||||
* Webserver->sendHeader(F("Content-Disposition"), F("attachment; filename=myfile.txt"));
|
||||
* @param sendRecord: will receive the memory address as "uint8_t* addr" and should consume the current entry/record
|
||||
* @example myStruct_t *entry = (myStruct_t*)addr;
|
||||
* Then make useful Strings and send it, i.e.: WebServer->sendContent_P(myString);
|
||||
* Then make useful Strings and send it, i.e.: Webserver->sendContent_P(myString);
|
||||
* @param sendFooter: finish the download, should implement at least:
|
||||
* @example WebServer->sendContent("");
|
||||
* @example Webserver->sendContent("");
|
||||
*/
|
||||
void FLOG::startDownload(size_t size, CallbackNoArgs sendHeader, CallbackWithArgs sendRecord, CallbackNoArgs sendFooter){
|
||||
|
||||
|
@ -708,8 +708,7 @@ void EspRestart(void)
|
||||
ResetPwm();
|
||||
WifiShutdown(true);
|
||||
CrashDumpClear(); // Clear the stack dump in RTC
|
||||
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
|
||||
ESP_reset();
|
||||
ESP_Restart();
|
||||
}
|
||||
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
|
@ -315,12 +315,13 @@ enum DevGroupItem { DGR_ITEM_EOL, DGR_ITEM_STATUS,
|
||||
DGR_ITEM_POWER, DGR_ITEM_DIMMER_RANGE,
|
||||
// Add new 32-bit items before this line
|
||||
DGR_ITEM_LAST_32BIT, DGR_ITEM_MAX_32BIT = 191,
|
||||
DGR_ITEM_EVENT,
|
||||
// Add new string items before this line
|
||||
DGR_ITEM_LAST_STRING, DGR_ITEM_MAX_STRING = 223,
|
||||
DGR_ITEM_LIGHT_CHANNELS };
|
||||
|
||||
enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE_LIGHT_FADE = 4, DGR_SHARE_LIGHT_SCHEME = 8,
|
||||
DGR_SHARE_LIGHT_COLOR = 16, DGR_SHARE_DIMMER_SETTINGS = 32 };
|
||||
DGR_SHARE_LIGHT_COLOR = 16, DGR_SHARE_DIMMER_SETTINGS = 32, DGR_SHARE_EVENT = 64 };
|
||||
|
||||
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
||||
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
||||
|
@ -190,6 +190,12 @@ char web_log[WEB_LOG_SIZE] = {'\0'}; // Web log buffer
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
#ifdef ESP32
|
||||
#ifdef DISABLE_ESP32_BROWNOUT
|
||||
DisableBrownout(); // Workaround possible weak LDO resulting in brownout detection during Wifi connection
|
||||
#endif
|
||||
#endif
|
||||
|
||||
global_state.data = 3; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
||||
|
||||
RtcRebootLoad();
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#ifdef ESP32
|
||||
#include <esp8266toEsp32.h>
|
||||
#define PACKED __attribute((__packed__))
|
||||
// Modul
|
||||
#undef MODULE
|
||||
#define MODULE WEMOS // [Module] Select default model
|
||||
@ -10,21 +9,6 @@
|
||||
|
||||
#ifdef ESP8266
|
||||
// ESP8266
|
||||
#define PACKED
|
||||
#define ESP_rtcUserMemoryWrite(offset, data, size) ESP.rtcUserMemoryWrite(offset, data, size)
|
||||
#define ESP_rtcUserMemoryRead(offset, data, size) ESP.rtcUserMemoryRead(offset, data, size)
|
||||
#define ESP_getResetReason() ESP.getResetReason()
|
||||
#define ESP_reset() ESP.reset()
|
||||
#define ESP_getBootVersion() ESP.getBootVersion()
|
||||
#define ESP_getFlashChipId() ESP.getFlashChipId()
|
||||
#define ESP_getFlashChipRealSize() ESP.getFlashChipRealSize()
|
||||
#define ESP_getSketchSize() ESP.getSketchSize()
|
||||
#define ESP_getChipId() ESP.getChipId()
|
||||
//
|
||||
// we need different ESP_flashRead for ESP32
|
||||
//
|
||||
#define ESP_flashReadHeader(offset, data, size) ESP.flashRead(offset, data, size)
|
||||
#define ESP_flashRead(offset, data, size) ESP.flashRead(offset, data, size)
|
||||
//
|
||||
// UDP
|
||||
#define PortUdp_write(p,n) PortUdp.write(p, n)
|
||||
|
@ -50,7 +50,7 @@
|
||||
#define USE_DEEPSLEEP // Add support for deepsleep (+1k code)
|
||||
#undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer
|
||||
//#define USE_HOTPLUG // Add support for sensor HotPlug
|
||||
#undef USE_DEVICE_GROUPS // Disable support for device groups (+5k6 code)
|
||||
//#undef USE_DEVICE_GROUPS // Disable support for device groups (+5k6 code)
|
||||
#undef USE_PWM_DIMMER // Disable support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code)
|
||||
#undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm (+4k5 code)
|
||||
#undef USE_SONOFF_D1 // DIsable support for Sonoff D1 Dimmer (+0k7 code)
|
||||
|
@ -713,11 +713,12 @@ const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcFLFLolD6D7D5D8D0A0";
|
||||
// esp32 has more pins
|
||||
#define USER_MODULE 255
|
||||
#define MAX_GPIO_PIN 40 // Number of supported GPIO
|
||||
#define MIN_FLASH_PINS 6 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8, 9, 10 and 11)
|
||||
#define ADC0_PIN 36 // Pin number of ADC0
|
||||
#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11)
|
||||
#define ADC0_PIN 33 // Pin number of ADC0
|
||||
#define WEMOS_MODULE 0 // Wemos module
|
||||
|
||||
const char PINS_WEMOS[] PROGMEM = "00TX02RX04050607080910111213141516171819202122232425262728293031A4A5A6A7A03738A3";
|
||||
// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839
|
||||
const char PINS_WEMOS[] PROGMEM = "IOTXIORXIOIOflashcFLFLolIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOA6A7A0IoIoA3";
|
||||
|
||||
#endif // ESP8266
|
||||
|
||||
|
@ -45,106 +45,61 @@
|
||||
/********************************************************************************************/
|
||||
// Supported hardware modules
|
||||
enum SupportedModules {
|
||||
WEMOS,
|
||||
ESP32_CAM,
|
||||
MAXMODULE
|
||||
};
|
||||
WEMOS, ESP32_CAM_AITHINKER,
|
||||
MAXMODULE};
|
||||
|
||||
const char kModuleNames[] PROGMEM =
|
||||
"WeMos D1 ESP32|ESP32 CAM|"
|
||||
;
|
||||
"ESP32-DevKit|ESP32 Cam AiThinker";
|
||||
|
||||
// Default module settings
|
||||
const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
|
||||
WEMOS,
|
||||
ESP32_CAM
|
||||
ESP32_CAM_AITHINKER
|
||||
};
|
||||
|
||||
const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||
{ // "WeMos D1 ESP32", // Any ESP32 device like WeMos and NodeMCU hardware (ESP32)
|
||||
GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
|
||||
GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
|
||||
GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
|
||||
GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
|
||||
GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
|
||||
GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
|
||||
// 0, //6
|
||||
// 0, //7
|
||||
// 0, //8
|
||||
// 0, //9
|
||||
// 0, //10
|
||||
// 0, //11
|
||||
GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.)
|
||||
GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
|
||||
GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
|
||||
GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.)
|
||||
GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
|
||||
GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
|
||||
GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7
|
||||
GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0
|
||||
0, //20
|
||||
0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN
|
||||
GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1
|
||||
GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE
|
||||
0, //24
|
||||
GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
|
||||
GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
|
||||
GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
|
||||
0, //28
|
||||
0, //29
|
||||
0, //30
|
||||
0, //31
|
||||
GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
|
||||
GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
|
||||
GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
|
||||
GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
|
||||
GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
|
||||
0, //37 NO PULLUP
|
||||
0, //38 NO PULLUP
|
||||
GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
|
||||
},
|
||||
{ //"ESP32 CAM",
|
||||
GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
|
||||
GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
|
||||
GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
|
||||
GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
|
||||
GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
|
||||
GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
|
||||
// 0, //6
|
||||
// 0, //7
|
||||
// 0, //8
|
||||
// 0, //9
|
||||
// 0, //10
|
||||
// 0, //11
|
||||
GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.)
|
||||
GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
|
||||
GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
|
||||
GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.)
|
||||
GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
|
||||
GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
|
||||
GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7
|
||||
GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0
|
||||
0, //20
|
||||
0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN
|
||||
GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1
|
||||
GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE
|
||||
0, //24
|
||||
GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
|
||||
GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
|
||||
GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
|
||||
0, //28
|
||||
0, //29
|
||||
0, //30
|
||||
0, //31
|
||||
GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
|
||||
GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
|
||||
GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
|
||||
GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
|
||||
GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
|
||||
0, //37 NO PULLUP
|
||||
0, //38 NO PULLUP
|
||||
GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
|
||||
}
|
||||
const mytmplt kModules PROGMEM =
|
||||
{ // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32)
|
||||
GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
|
||||
GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
|
||||
GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
|
||||
GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
|
||||
GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
|
||||
GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
|
||||
//6 IO GPIO6, Flash CLK
|
||||
//7 IO GPIO7, Flash D0
|
||||
//8 IO GPIO8, Flash D1
|
||||
GPIO_USER, //9 IO GPIO9, Flash D2, U1RXD
|
||||
GPIO_USER, //10 IO GPIO10, Flash D3, U1TXD
|
||||
//11 IO GPIO11, Flash CMD
|
||||
GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.)
|
||||
GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
|
||||
GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
|
||||
GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.)
|
||||
GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
|
||||
GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
|
||||
GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7
|
||||
GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0
|
||||
0, //20
|
||||
GPIO_USER, //21 IO GPIO21, VSPIHD, EMAC_TX_EN
|
||||
GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1
|
||||
GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE
|
||||
0, //24
|
||||
GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
|
||||
GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
|
||||
GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
|
||||
0, //28
|
||||
0, //29
|
||||
0, //30
|
||||
0, //31
|
||||
GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
|
||||
GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
|
||||
GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
|
||||
GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
|
||||
GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
|
||||
0, //37 NO PULLUP
|
||||
0, //38 NO PULLUP
|
||||
GPIO_USER, //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
|
||||
0 // Flag
|
||||
};
|
||||
|
||||
#endif // ESP32
|
||||
|
@ -109,7 +109,7 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM =
|
||||
"}"
|
||||
"};"
|
||||
"if (rfsh) {"
|
||||
"x.open('GET','.?m=1'+a,true);" // ?m related to WebServer->hasArg("m")
|
||||
"x.open('GET','.?m=1'+a,true);" // ?m related to Webserver->hasArg("m")
|
||||
"x.send();"
|
||||
"lt=setTimeout(la,%d);" // Settings.web_refresh
|
||||
"}"
|
||||
@ -146,7 +146,7 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM =
|
||||
"eb('l1').innerHTML=s;"
|
||||
"}"
|
||||
"};"
|
||||
"x.open('GET','.?m=1'+a,true);" // ?m related to WebServer->hasArg("m")
|
||||
"x.open('GET','.?m=1'+a,true);" // ?m related to Webserver->hasArg("m")
|
||||
"x.send();"
|
||||
"lt=setTimeout(la,%d);" // Settings.web_refresh
|
||||
"}";
|
||||
@ -205,7 +205,7 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM =
|
||||
"sn=t.scrollTop;"
|
||||
"}"
|
||||
"};"
|
||||
"x.open('GET','cs?c2='+id+o,true);" // Related to WebServer->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp))
|
||||
"x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp))
|
||||
"x.send();"
|
||||
"}"
|
||||
"lt=setTimeout(l,%d);"
|
||||
@ -261,21 +261,14 @@ const char HTTP_SCRIPT_TEMPLATE[] PROGMEM =
|
||||
"as=o.shift();" // Complete ADC0 list
|
||||
"g=o.shift().split(',');" // Array separator
|
||||
"j=0;"
|
||||
// "for(i=0;i<13;i++){" // Supports 13 GPIOs
|
||||
"for(i=0;i<" STR(MAX_USER_PINS) ";i++){" // Supports 13 GPIOs
|
||||
#ifdef ESP8266
|
||||
"if(6==i){j=9;}"
|
||||
"if(8==i){j=12;}"
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
"if(6==i){j=12;}"
|
||||
#endif
|
||||
"sk(g[i],j);" // Set GPIO
|
||||
"j++;"
|
||||
"}"
|
||||
"g=o.shift();" // FLAG
|
||||
"os=as;"
|
||||
// "sk(g&15,17);" // Set ADC0
|
||||
"sk(g&15," STR(ADC0_PIN) ");" // Set ADC0
|
||||
"g>>=4;"
|
||||
"for(i=0;i<" STR(GPIO_FLAG_USED) ";i++){"
|
||||
@ -295,16 +288,15 @@ const char HTTP_SCRIPT_TEMPLATE[] PROGMEM =
|
||||
|
||||
"function x2(a){"
|
||||
"os=a.responseText;"
|
||||
// "sk(17,99);" // 17 = WEMOS
|
||||
"sk(" STR(WEMOS_MODULE) ",99);" // 17 = WEMOS
|
||||
"st(" STR(USER_MODULE) ");"
|
||||
"}"
|
||||
|
||||
#ifdef USE_JAVASCRIPT_ES6
|
||||
"sl=()=>ld('tp?m=1',x2);" // ?m related to WebServer->hasArg("m")
|
||||
"sl=()=>ld('tp?m=1',x2);" // ?m related to Webserver->hasArg("m")
|
||||
#else
|
||||
"function sl(){"
|
||||
"ld('tp?m=1',x2);" // ?m related to WebServer->hasArg("m")
|
||||
"ld('tp?m=1',x2);" // ?m related to Webserver->hasArg("m")
|
||||
"}"
|
||||
#endif
|
||||
|
||||
@ -321,15 +313,13 @@ const char HTTP_SCRIPT_MODULE2[] PROGMEM =
|
||||
"}"
|
||||
"function x3(a){" // ADC0
|
||||
"os=a.responseText;"
|
||||
// "sk(%d,17);"
|
||||
"sk(%d," STR(ADC0_PIN) ");"
|
||||
"}"
|
||||
"function sl(){"
|
||||
"ld('md?m=1',x1);" // ?m related to WebServer->hasArg("m")
|
||||
"ld('md?g=1',x2);" // ?g related to WebServer->hasArg("g")
|
||||
// "if(eb('g17')){"
|
||||
"ld('md?m=1',x1);" // ?m related to Webserver->hasArg("m")
|
||||
"ld('md?g=1',x2);" // ?g related to Webserver->hasArg("g")
|
||||
"if(eb('g" STR(ADC0_PIN) "')){"
|
||||
"ld('md?a=1',x3);" // ?a related to WebServer->hasArg("a")
|
||||
"ld('md?a=1',x3);" // ?a related to Webserver->hasArg("a")
|
||||
"}"
|
||||
"}"
|
||||
"wl(sl);";
|
||||
@ -544,7 +534,7 @@ const uint16_t DNS_PORT = 53;
|
||||
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY};
|
||||
|
||||
DNSServer *DnsServer;
|
||||
ESP8266WebServer *WebServer;
|
||||
ESP8266WebServer *Webserver;
|
||||
|
||||
struct WEB {
|
||||
String chunk_buffer = ""; // Could be max 2 * CHUNKED_BUFFER_SIZE
|
||||
@ -561,7 +551,7 @@ struct WEB {
|
||||
// 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);
|
||||
String s = Webserver->arg(arg);
|
||||
strlcpy(out, s.c_str(), max);
|
||||
// out[max-1] = '\0'; // Ensure terminating NUL
|
||||
}
|
||||
@ -574,7 +564,7 @@ void ShowWebSource(uint32_t source)
|
||||
{
|
||||
if ((source > 0) && (source < SRC_MAX)) {
|
||||
char stemp1[20];
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SRC: %s from %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), WebServer->client().remoteIP().toString().c_str());
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SRC: %s from %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), Webserver->client().remoteIP().toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,28 +579,28 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||
{
|
||||
if (!Settings.web_refresh) { Settings.web_refresh = HTTP_REFRESH_TIME; }
|
||||
if (!Web.state) {
|
||||
if (!WebServer) {
|
||||
WebServer = new ESP8266WebServer((HTTP_MANAGER == type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT);
|
||||
WebServer->on("/", HandleRoot);
|
||||
WebServer->onNotFound(HandleNotFound);
|
||||
WebServer->on("/up", HandleUpgradeFirmware);
|
||||
WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA
|
||||
WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop);
|
||||
WebServer->on("/u2", HTTP_OPTIONS, HandlePreflightRequest);
|
||||
WebServer->on("/cs", HTTP_GET, HandleConsole);
|
||||
WebServer->on("/cs", HTTP_OPTIONS, HandlePreflightRequest);
|
||||
WebServer->on("/cm", HandleHttpCommand);
|
||||
if (!Webserver) {
|
||||
Webserver = new ESP8266WebServer((HTTP_MANAGER == type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT);
|
||||
Webserver->on("/", HandleRoot);
|
||||
Webserver->onNotFound(HandleNotFound);
|
||||
Webserver->on("/up", HandleUpgradeFirmware);
|
||||
Webserver->on("/u1", HandleUpgradeFirmwareStart); // OTA
|
||||
Webserver->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop);
|
||||
Webserver->on("/u2", HTTP_OPTIONS, HandlePreflightRequest);
|
||||
Webserver->on("/cs", HTTP_GET, HandleConsole);
|
||||
Webserver->on("/cs", HTTP_OPTIONS, HandlePreflightRequest);
|
||||
Webserver->on("/cm", HandleHttpCommand);
|
||||
#ifndef FIRMWARE_MINIMAL
|
||||
WebServer->on("/cn", HandleConfiguration);
|
||||
WebServer->on("/md", HandleModuleConfiguration);
|
||||
WebServer->on("/wi", HandleWifiConfiguration);
|
||||
WebServer->on("/lg", HandleLoggingConfiguration);
|
||||
WebServer->on("/tp", HandleTemplateConfiguration);
|
||||
WebServer->on("/co", HandleOtherConfiguration);
|
||||
WebServer->on("/dl", HandleBackupConfiguration);
|
||||
WebServer->on("/rs", HandleRestoreConfiguration);
|
||||
WebServer->on("/rt", HandleResetConfiguration);
|
||||
WebServer->on("/in", HandleInformation);
|
||||
Webserver->on("/cn", HandleConfiguration);
|
||||
Webserver->on("/md", HandleModuleConfiguration);
|
||||
Webserver->on("/wi", HandleWifiConfiguration);
|
||||
Webserver->on("/lg", HandleLoggingConfiguration);
|
||||
Webserver->on("/tp", HandleTemplateConfiguration);
|
||||
Webserver->on("/co", HandleOtherConfiguration);
|
||||
Webserver->on("/dl", HandleBackupConfiguration);
|
||||
Webserver->on("/rs", HandleRestoreConfiguration);
|
||||
Webserver->on("/rt", HandleResetConfiguration);
|
||||
Webserver->on("/in", HandleInformation);
|
||||
XdrvCall(FUNC_WEB_ADD_HANDLER);
|
||||
XsnsCall(FUNC_WEB_ADD_HANDLER);
|
||||
#endif // Not FIRMWARE_MINIMAL
|
||||
@ -619,9 +609,9 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||
|
||||
// Collect User-Agent for Alexa Hue Emulation
|
||||
// This is used in xdrv_20_hue.ino in function findEchoGeneration()
|
||||
WebServer->collectHeaders(HEADER_KEYS, sizeof(HEADER_KEYS)/sizeof(char*));
|
||||
Webserver->collectHeaders(HEADER_KEYS, sizeof(HEADER_KEYS)/sizeof(char*));
|
||||
|
||||
WebServer->begin(); // Web server start
|
||||
Webserver->begin(); // Web server start
|
||||
}
|
||||
if (Web.state != type) {
|
||||
#if LWIP_IPV6
|
||||
@ -639,7 +629,7 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||
void StopWebserver(void)
|
||||
{
|
||||
if (Web.state) {
|
||||
WebServer->close();
|
||||
Webserver->close();
|
||||
Web.state = HTTP_OFF;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_STOPPED));
|
||||
}
|
||||
@ -684,7 +674,7 @@ void WifiManagerBegin(bool reset_only)
|
||||
void PollDnsWebserver(void)
|
||||
{
|
||||
if (DnsServer) { DnsServer->processNextRequest(); }
|
||||
if (WebServer) { WebServer->handleClient(); }
|
||||
if (Webserver) { Webserver->handleClient(); }
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
@ -692,7 +682,7 @@ void PollDnsWebserver(void)
|
||||
bool WebAuthenticate(void)
|
||||
{
|
||||
if (strlen(SettingsText(SET_WEBPWD)) && (HTTP_MANAGER_RESET_ONLY != Web.state)) {
|
||||
return WebServer->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD));
|
||||
return Webserver->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@ -705,7 +695,7 @@ bool HttpCheckPriviledgedAccess(bool autorequestauth = true)
|
||||
return false;
|
||||
}
|
||||
if (autorequestauth && !WebAuthenticate()) {
|
||||
WebServer->requestAuthentication();
|
||||
Webserver->requestAuthentication();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -714,15 +704,15 @@ bool HttpCheckPriviledgedAccess(bool autorequestauth = true)
|
||||
void HttpHeaderCors(void)
|
||||
{
|
||||
if (strlen(SettingsText(SET_CORS))) {
|
||||
WebServer->sendHeader(F("Access-Control-Allow-Origin"), SettingsText(SET_CORS));
|
||||
Webserver->sendHeader(F("Access-Control-Allow-Origin"), SettingsText(SET_CORS));
|
||||
}
|
||||
}
|
||||
|
||||
void WSHeaderSend(void)
|
||||
{
|
||||
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"));
|
||||
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"));
|
||||
HttpHeaderCors();
|
||||
}
|
||||
|
||||
@ -733,7 +723,7 @@ void WSHeaderSend(void)
|
||||
void WSSend(int code, int ctype, const String& content)
|
||||
{
|
||||
char ct[25]; // strlen("application/octet-stream") +1 = Longest Content type string
|
||||
WebServer->send(code, GetTextIndexed(ct, sizeof(ct), ctype, kContentTypes), content);
|
||||
Webserver->send(code, GetTextIndexed(ct, sizeof(ct), ctype, kContentTypes), content);
|
||||
}
|
||||
|
||||
/**********************************************************************************************
|
||||
@ -742,13 +732,13 @@ void WSSend(int code, int ctype, const String& content)
|
||||
|
||||
void WSContentBegin(int code, int ctype)
|
||||
{
|
||||
WebServer->client().flush();
|
||||
Webserver->client().flush();
|
||||
WSHeaderSend();
|
||||
#ifdef ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
WebServer->sendHeader(F("Accept-Ranges"),F("none"));
|
||||
WebServer->sendHeader(F("Transfer-Encoding"),F("chunked"));
|
||||
Webserver->sendHeader(F("Accept-Ranges"),F("none"));
|
||||
Webserver->sendHeader(F("Transfer-Encoding"),F("chunked"));
|
||||
#endif
|
||||
WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||
Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||
WSSend(code, ctype, ""); // Signal start of chunked content
|
||||
Web.chunk_buffer = "";
|
||||
}
|
||||
@ -761,9 +751,9 @@ void _WSContentSend(const String& content) // Low level sendContent for a
|
||||
const char * footer = "\r\n";
|
||||
char chunk_size[11];
|
||||
sprintf(chunk_size, "%x\r\n", len);
|
||||
WebServer->sendContent(String() + chunk_size + content + footer);
|
||||
Webserver->sendContent(String() + chunk_size + content + footer);
|
||||
#else
|
||||
WebServer->sendContent(content);
|
||||
Webserver->sendContent(content);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DEBUG_DRIVER
|
||||
@ -849,8 +839,8 @@ void WSContentSend_PD(const char* formatP, ...) // Content send snprintf_P ch
|
||||
|
||||
void WSContentStart_P(const char* title, bool auth)
|
||||
{
|
||||
if (auth && strlen(SettingsText(SET_WEBPWD)) && !WebServer->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD))) {
|
||||
return WebServer->requestAuthentication();
|
||||
if (auth && strlen(SettingsText(SET_WEBPWD)) && !Webserver->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD))) {
|
||||
return Webserver->requestAuthentication();
|
||||
}
|
||||
|
||||
WSContentBegin(200, CT_HTML);
|
||||
@ -961,7 +951,7 @@ void WSContentEnd(void)
|
||||
{
|
||||
WSContentFlush(); // Flush chunk buffer
|
||||
_WSContentSend(""); // Signal end of chunked content
|
||||
WebServer->client().stop();
|
||||
Webserver->client().stop();
|
||||
}
|
||||
|
||||
void WSContentStop(void)
|
||||
@ -1043,17 +1033,17 @@ void HandleRoot(void)
|
||||
{
|
||||
if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page.
|
||||
|
||||
if (WebServer->hasArg("rst")) {
|
||||
if (Webserver->hasArg("rst")) {
|
||||
WebRestart(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (WifiIsInManagerMode()) {
|
||||
#ifndef FIRMWARE_MINIMAL
|
||||
if (strlen(SettingsText(SET_WEBPWD)) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1")) && HTTP_MANAGER_RESET_ONLY != Web.state) {
|
||||
if (strlen(SettingsText(SET_WEBPWD)) && !(Webserver->hasArg("USER1")) && !(Webserver->hasArg("PASS1")) && HTTP_MANAGER_RESET_ONLY != Web.state) {
|
||||
HandleWifiLogin();
|
||||
} else {
|
||||
if (!strlen(SettingsText(SET_WEBPWD)) || (((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == SettingsText(SET_WEBPWD) )) || HTTP_MANAGER_RESET_ONLY == Web.state)) {
|
||||
if (!strlen(SettingsText(SET_WEBPWD)) || (((Webserver->arg("USER1") == WEB_USERNAME ) && (Webserver->arg("PASS1") == SettingsText(SET_WEBPWD) )) || HTTP_MANAGER_RESET_ONLY == Web.state)) {
|
||||
HandleWifiConfiguration();
|
||||
} else {
|
||||
// wrong user and pass
|
||||
@ -1243,11 +1233,11 @@ void HandleRoot(void)
|
||||
bool HandleRootStatusRefresh(void)
|
||||
{
|
||||
if (!WebAuthenticate()) {
|
||||
WebServer->requestAuthentication();
|
||||
Webserver->requestAuthentication();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!WebServer->hasArg("m")) { // Status refresh requested
|
||||
if (!Webserver->hasArg("m")) { // Status refresh requested
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1429,7 +1419,7 @@ void HandleTemplateConfiguration(void)
|
||||
{
|
||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
TemplateSaveSettings();
|
||||
WebRestart(1);
|
||||
return;
|
||||
@ -1437,7 +1427,7 @@ void HandleTemplateConfiguration(void)
|
||||
|
||||
char stemp[30]; // Template number and Sensor name
|
||||
|
||||
if (WebServer->hasArg("m")) {
|
||||
if (Webserver->hasArg("m")) {
|
||||
WSContentBegin(200, CT_PLAIN);
|
||||
for (uint32_t i = 0; i < sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'0'>Sonoff Basic (1)}3"
|
||||
uint32_t midx = pgm_read_byte(kModuleNiceList + i);
|
||||
@ -1529,13 +1519,8 @@ void TemplateSaveSettings(void)
|
||||
|
||||
uint32_t j = 0;
|
||||
for (uint32_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
||||
#ifdef ESP8266
|
||||
if (6 == i) { j = 9; }
|
||||
if (8 == i) { j = 12; }
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
if (6 == i) { j = 12; }
|
||||
#endif // ESP32
|
||||
snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), j);
|
||||
WebGetArg(webindex, tmp, sizeof(tmp)); // GPIO
|
||||
uint8_t gpio = atoi(tmp);
|
||||
@ -1543,12 +1528,11 @@ void TemplateSaveSettings(void)
|
||||
j++;
|
||||
}
|
||||
|
||||
// WebGetArg("g17", tmp, sizeof(tmp)); // FLAG - ADC0
|
||||
WebGetArg("g" STR(ADC0_PIN), tmp, sizeof(tmp)); // FLAG - ADC0
|
||||
uint32_t flag = atoi(tmp);
|
||||
for (uint32_t i = 0; i < GPIO_FLAG_USED; i++) {
|
||||
snprintf_P(webindex, sizeof(webindex), PSTR("c%d"), i);
|
||||
uint32_t state = WebServer->hasArg(webindex) << i +4; // FLAG
|
||||
uint32_t state = Webserver->hasArg(webindex) << i +4; // FLAG
|
||||
flag += state;
|
||||
}
|
||||
WebGetArg("g99", tmp, sizeof(tmp)); // BASE
|
||||
@ -1564,7 +1548,7 @@ void HandleModuleConfiguration(void)
|
||||
{
|
||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
ModuleSaveSettings();
|
||||
WebRestart(1);
|
||||
return;
|
||||
@ -1575,7 +1559,7 @@ void HandleModuleConfiguration(void)
|
||||
myio cmodule;
|
||||
ModuleGpios(&cmodule);
|
||||
|
||||
if (WebServer->hasArg("m")) {
|
||||
if (Webserver->hasArg("m")) {
|
||||
WSContentBegin(200, CT_PLAIN);
|
||||
uint32_t vidx = 0;
|
||||
for (uint32_t i = 0; i <= sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'255'>UserTemplate (0)}3" - "}2'0'>Sonoff Basic (1)}3"
|
||||
@ -1592,7 +1576,7 @@ void HandleModuleConfiguration(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (WebServer->hasArg("g")) {
|
||||
if (Webserver->hasArg("g")) {
|
||||
WSContentBegin(200, CT_PLAIN);
|
||||
for (uint32_t j = 0; j < sizeof(kGpioNiceList); j++) {
|
||||
midx = pgm_read_byte(kGpioNiceList + j);
|
||||
@ -1605,7 +1589,7 @@ void HandleModuleConfiguration(void)
|
||||
}
|
||||
|
||||
#ifndef USE_ADC_VCC
|
||||
if (WebServer->hasArg("a")) {
|
||||
if (Webserver->hasArg("a")) {
|
||||
WSContentBegin(200, CT_PLAIN);
|
||||
for (uint32_t j = 0; j < ADC0_END; j++) {
|
||||
WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, j, GetTextIndexed(stemp, sizeof(stemp), j, kAdc0Names), j);
|
||||
@ -1675,17 +1659,28 @@ void ModuleSaveSettings(void)
|
||||
if (ValidGPIO(i, cmodule.io[i])) {
|
||||
snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), i);
|
||||
WebGetArg(webindex, 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]);
|
||||
uint8_t value = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
#ifdef ESP8266
|
||||
Settings.my_gp.io[i] = value;
|
||||
#else // ESP32
|
||||
if (i == ADC0_PIN) {
|
||||
Settings.my_adc0 = value;
|
||||
} else {
|
||||
Settings.my_gp.io[i] = value;
|
||||
}
|
||||
#endif // ESP8266 - ESP32
|
||||
gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef ESP8266
|
||||
#ifndef USE_ADC_VCC
|
||||
// WebGetArg("g17", tmp, sizeof(tmp));
|
||||
WebGetArg("g" STR(ADC0_PIN), tmp, sizeof(tmp));
|
||||
Settings.my_adc0 = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
gpios += F(", " D_ADC "0 "); gpios += String(Settings.my_adc0);
|
||||
#endif // USE_ADC_VCC
|
||||
#endif // ESP8266
|
||||
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MODULE "%s " D_CMND_MODULE "%s"), ModuleName().c_str(), gpios.c_str());
|
||||
}
|
||||
@ -1720,7 +1715,7 @@ void HandleWifiConfiguration(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI);
|
||||
|
||||
if (WebServer->hasArg("save") && HTTP_MANAGER_RESET_ONLY != Web.state) {
|
||||
if (Webserver->hasArg("save") && HTTP_MANAGER_RESET_ONLY != Web.state) {
|
||||
WifiSaveSettings();
|
||||
WebRestart(2);
|
||||
return;
|
||||
@ -1731,7 +1726,7 @@ void HandleWifiConfiguration(void)
|
||||
WSContentSendStyle();
|
||||
|
||||
if (HTTP_MANAGER_RESET_ONLY != Web.state) {
|
||||
if (WebServer->hasArg("scan")) {
|
||||
if (Webserver->hasArg("scan")) {
|
||||
#ifdef USE_EMULATION
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
@ -1844,7 +1839,7 @@ void HandleLoggingConfiguration(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_LOGGING);
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
LoggingSaveSettings();
|
||||
HandleConfiguration();
|
||||
return;
|
||||
@ -1909,7 +1904,7 @@ void HandleOtherConfiguration(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_OTHER);
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
OtherSaveSettings();
|
||||
WebRestart(1);
|
||||
return;
|
||||
@ -1973,7 +1968,7 @@ void OtherSaveSettings(void)
|
||||
|
||||
WebGetArg("wp", tmp, sizeof(tmp));
|
||||
SettingsUpdateText(SET_WEBPWD, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? SettingsText(SET_WEBPWD) : tmp);
|
||||
Settings.flag.mqtt_enabled = WebServer->hasArg("b1"); // SetOption3 - Enable MQTT
|
||||
Settings.flag.mqtt_enabled = Webserver->hasArg("b1"); // SetOption3 - Enable MQTT
|
||||
#ifdef USE_EMULATION
|
||||
UdpDisconnect();
|
||||
#if defined(USE_EMULATION_WEMO) || defined(USE_EMULATION_HUE)
|
||||
@ -1994,7 +1989,7 @@ void OtherSaveSettings(void)
|
||||
|
||||
/*
|
||||
// This sometimes provides intermittent watchdog
|
||||
bool template_activate = WebServer->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command
|
||||
bool template_activate = Webserver->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command
|
||||
WebGetArg("t1", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255}
|
||||
char svalue[128];
|
||||
@ -2010,7 +2005,7 @@ void OtherSaveSettings(void)
|
||||
*/
|
||||
WebGetArg("t1", tmp, sizeof(tmp));
|
||||
if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255}
|
||||
snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (WebServer->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : "");
|
||||
snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (Webserver->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : "");
|
||||
ExecuteWebCommand(message, SRC_WEBGUI);
|
||||
}
|
||||
}
|
||||
@ -2025,8 +2020,8 @@ void HandleBackupConfiguration(void)
|
||||
|
||||
if (!SettingsBufferAlloc()) { return; }
|
||||
|
||||
WiFiClient myClient = WebServer->client();
|
||||
WebServer->setContentLength(sizeof(Settings));
|
||||
WiFiClient myClient = Webserver->client();
|
||||
Webserver->setContentLength(sizeof(Settings));
|
||||
|
||||
char attachment[TOPSZ];
|
||||
|
||||
@ -2036,7 +2031,7 @@ void HandleBackupConfiguration(void)
|
||||
char hostname[sizeof(my_hostname)];
|
||||
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(hostname, my_hostname), my_version);
|
||||
|
||||
WebServer->sendHeader(F("Content-Disposition"), attachment);
|
||||
Webserver->sendHeader(F("Content-Disposition"), attachment);
|
||||
|
||||
WSSend(200, CT_STREAM, "");
|
||||
|
||||
@ -2127,7 +2122,11 @@ void HandleInformation(void)
|
||||
WSContentSend_P(PSTR("}1" D_BUILD_DATE_AND_TIME "}2%s"), GetBuildDateAndTime().c_str());
|
||||
WSContentSend_P(PSTR("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_CORE_RELEASE "/%s"), ESP.getSdkVersion());
|
||||
WSContentSend_P(PSTR("}1" D_UPTIME "}2%s"), GetUptime().c_str());
|
||||
#ifdef ESP8266
|
||||
WSContentSend_P(PSTR("}1" D_FLASH_WRITE_COUNT "}2%d at 0x%X"), Settings.save_flag, GetSettingsAddress());
|
||||
#else
|
||||
WSContentSend_P(PSTR("}1" D_FLASH_WRITE_COUNT "}2%d"), Settings.save_flag);
|
||||
#endif
|
||||
WSContentSend_P(PSTR("}1" D_BOOT_COUNT "}2%d"), Settings.bootcount);
|
||||
WSContentSend_P(PSTR("}1" D_RESTART_REASON "}2%s"), GetResetReason().c_str());
|
||||
uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present;
|
||||
@ -2201,8 +2200,10 @@ void HandleInformation(void)
|
||||
|
||||
WSContentSend_P(PSTR("}1}2 ")); // Empty line
|
||||
WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d"), ESP_getChipId());
|
||||
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP_getFlashChipId());
|
||||
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP_getFlashChipRealSize() / 1024);
|
||||
#ifdef ESP8266
|
||||
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP.getFlashChipId());
|
||||
#endif
|
||||
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP.getFlashChipRealSize() / 1024);
|
||||
WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%dkB"), ESP.getFlashChipSize() / 1024);
|
||||
WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%dkB"), ESP_getSketchSize() / 1024);
|
||||
WSContentSend_P(PSTR("}1" D_FREE_PROGRAM_SPACE "}2%dkB"), ESP.getFreeSketchSpace() / 1024);
|
||||
@ -2336,7 +2337,7 @@ void HandleUploadLoop(void)
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPUpload& upload = WebServer->upload();
|
||||
HTTPUpload& upload = Webserver->upload();
|
||||
|
||||
if (UPLOAD_FILE_START == upload.status) {
|
||||
restart_flag = 60;
|
||||
@ -2498,6 +2499,16 @@ void HandleUploadLoop(void)
|
||||
} else {
|
||||
valid_settings = (settings_buffer[0] == CONFIG_FILE_SIGN);
|
||||
}
|
||||
|
||||
if (valid_settings) {
|
||||
#ifdef ESP8266
|
||||
valid_settings = (0 == settings_buffer[0xF36]); // Settings.config_version
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
valid_settings = (1 == settings_buffer[0xF36]); // Settings.config_version
|
||||
#endif // ESP32
|
||||
}
|
||||
|
||||
if (valid_settings) {
|
||||
SettingsDefaultSet2();
|
||||
memcpy((char*)&Settings +16, settings_buffer +16, sizeof(Settings) -16);
|
||||
@ -2549,8 +2560,8 @@ void HandleUploadLoop(void)
|
||||
void HandlePreflightRequest(void)
|
||||
{
|
||||
HttpHeaderCors();
|
||||
WebServer->sendHeader(F("Access-Control-Allow-Methods"), F("GET, POST"));
|
||||
WebServer->sendHeader(F("Access-Control-Allow-Headers"), F("authorization"));
|
||||
Webserver->sendHeader(F("Access-Control-Allow-Methods"), F("GET, POST"));
|
||||
Webserver->sendHeader(F("Access-Control-Allow-Headers"), F("authorization"));
|
||||
WSSend(200, CT_HTML, "");
|
||||
}
|
||||
|
||||
@ -2562,54 +2573,54 @@ void HandleHttpCommand(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND));
|
||||
|
||||
bool valid = true;
|
||||
if (strlen(SettingsText(SET_WEBPWD))) {
|
||||
char tmp1[33];
|
||||
WebGetArg("user", tmp1, sizeof(tmp1));
|
||||
char tmp2[strlen(SettingsText(SET_WEBPWD)) +1];
|
||||
WebGetArg("password", tmp2, sizeof(tmp2));
|
||||
if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) { valid = false; }
|
||||
if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) {
|
||||
WSContentBegin(401, CT_JSON);
|
||||
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}"));
|
||||
WSContentEnd();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WSContentBegin(200, CT_JSON);
|
||||
if (valid) {
|
||||
uint32_t curridx = web_log_index;
|
||||
String svalue = WebServer->arg("cmnd");
|
||||
if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) {
|
||||
ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND);
|
||||
if (web_log_index != curridx) {
|
||||
uint32_t counter = curridx;
|
||||
WSContentSend_P(PSTR("{"));
|
||||
bool cflg = false;
|
||||
do {
|
||||
char* tmp;
|
||||
size_t len;
|
||||
GetLog(counter, &tmp, &len);
|
||||
if (len) {
|
||||
// [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}]
|
||||
char* JSON = (char*)memchr(tmp, '{', len);
|
||||
if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
|
||||
size_t JSONlen = len - (JSON - tmp);
|
||||
if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); }
|
||||
char stemp[JSONlen];
|
||||
strlcpy(stemp, JSON +1, JSONlen -2);
|
||||
WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp);
|
||||
cflg = true;
|
||||
}
|
||||
uint32_t curridx = web_log_index;
|
||||
String svalue = Webserver->arg("cmnd");
|
||||
if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) {
|
||||
ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND);
|
||||
if (web_log_index != curridx) {
|
||||
uint32_t counter = curridx;
|
||||
WSContentSend_P(PSTR("{"));
|
||||
bool cflg = false;
|
||||
do {
|
||||
char* tmp;
|
||||
size_t len;
|
||||
GetLog(counter, &tmp, &len);
|
||||
if (len) {
|
||||
// [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}]
|
||||
char* JSON = (char*)memchr(tmp, '{', len);
|
||||
if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
|
||||
size_t JSONlen = len - (JSON - tmp);
|
||||
if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); }
|
||||
char stemp[JSONlen];
|
||||
strlcpy(stemp, JSON +1, JSONlen -2);
|
||||
WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp);
|
||||
cflg = true;
|
||||
}
|
||||
counter++;
|
||||
counter &= 0xFF;
|
||||
if (!counter) counter++; // Skip 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
WSContentSend_P(PSTR("}"));
|
||||
} else {
|
||||
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}"));
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
counter &= 0xFF;
|
||||
if (!counter) counter++; // Skip 0 as it is not allowed
|
||||
} while (counter != web_log_index);
|
||||
WSContentSend_P(PSTR("}"));
|
||||
} else {
|
||||
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENTER_COMMAND " cmnd=\"}"));
|
||||
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}"));
|
||||
}
|
||||
} else {
|
||||
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}"));
|
||||
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENTER_COMMAND " cmnd=\"}"));
|
||||
}
|
||||
WSContentEnd();
|
||||
}
|
||||
@ -2620,7 +2631,7 @@ void HandleConsole(void)
|
||||
{
|
||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||
|
||||
if (WebServer->hasArg("c2")) { // Console refresh requested
|
||||
if (Webserver->hasArg("c2")) { // Console refresh requested
|
||||
HandleConsoleRefresh();
|
||||
return;
|
||||
}
|
||||
@ -2640,7 +2651,7 @@ void HandleConsoleRefresh(void)
|
||||
bool cflg = true;
|
||||
uint32_t counter = 0; // Initial start, should never be 0 again
|
||||
|
||||
String svalue = WebServer->arg("c1");
|
||||
String svalue = Webserver->arg("c1");
|
||||
if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) {
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), svalue.c_str());
|
||||
ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE);
|
||||
@ -2685,13 +2696,13 @@ void HandleConsoleRefresh(void)
|
||||
|
||||
void HandleNotFound(void)
|
||||
{
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), WebServer->uri().c_str());
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), Webserver->uri().c_str());
|
||||
|
||||
if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the error page.
|
||||
|
||||
#ifdef USE_EMULATION
|
||||
#ifdef USE_EMULATION_HUE
|
||||
String path = WebServer->uri();
|
||||
String path = Webserver->uri();
|
||||
if ((EMUL_HUE == Settings.flag2.emulation) && (path.startsWith("/api"))) {
|
||||
HandleHueApi(&path);
|
||||
} else
|
||||
@ -2699,9 +2710,9 @@ void HandleNotFound(void)
|
||||
#endif // USE_EMULATION
|
||||
{
|
||||
WSContentBegin(404, CT_PLAIN);
|
||||
WSContentSend_P(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 (uint32_t i = 0; i < WebServer->args(); i++) {
|
||||
WSContentSend_P(PSTR(" %s: %s\n"), WebServer->argName(i).c_str(), WebServer->arg(i).c_str());
|
||||
WSContentSend_P(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 (uint32_t i = 0; i < Webserver->args(); i++) {
|
||||
WSContentSend_P(PSTR(" %s: %s\n"), Webserver->argName(i).c_str(), Webserver->arg(i).c_str());
|
||||
}
|
||||
WSContentEnd();
|
||||
}
|
||||
@ -2711,12 +2722,12 @@ void HandleNotFound(void)
|
||||
bool CaptivePortal(void)
|
||||
{
|
||||
// Possible hostHeader: connectivitycheck.gstatic.com or 192.168.4.1
|
||||
if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader().c_str())) {
|
||||
if ((WifiIsInManagerMode()) && !ValidIpAddress(Webserver->hostHeader().c_str())) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
|
||||
|
||||
WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true);
|
||||
Webserver->sendHeader(F("Location"), String("http://") + Webserver->client().localIP().toString(), true);
|
||||
WSSend(302, CT_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->client().stop(); // Stop is needed because we sent no content length
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1028,6 +1028,9 @@ void CmndPowerRetain(void)
|
||||
}
|
||||
}
|
||||
Settings.flag.mqtt_power_retain = XdrvMailbox.payload; // CMND_POWERRETAIN
|
||||
if (Settings.flag.mqtt_power_retain) {
|
||||
Settings.flag4.only_json_message = 0; // SetOption90 - Disable non-json MQTT response
|
||||
}
|
||||
}
|
||||
ResponseCmndStateText(Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN
|
||||
}
|
||||
@ -1252,7 +1255,7 @@ void HandleMqttConfiguration(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MQTT);
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
MqttSaveSettings();
|
||||
WebRestart(1);
|
||||
return;
|
||||
@ -1334,7 +1337,7 @@ bool Xdrv02(uint8_t function)
|
||||
WSContentSend_P(HTTP_BTN_MENU_MQTT);
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration);
|
||||
Webserver->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
case FUNC_COMMAND:
|
||||
|
@ -1985,6 +1985,17 @@ bool isChannelGammaCorrected(uint32_t channel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// is the channel a regular PWM or ColorTemp control
|
||||
bool isChannelCT(uint32_t channel) {
|
||||
#ifdef ESP8266
|
||||
if (PHILIPS == my_module_type) {
|
||||
if ((LST_COLDWARM == Light.subtype) && (1 == channel)) { return true; } // PMW reserved for CT
|
||||
if ((LST_RGBCW == Light.subtype) && (4 == channel)) { return true; } // PMW reserved for CT
|
||||
}
|
||||
#endif // ESP8266
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate the Gamma correction, if any, for fading, using the fast Gamma curve (10 bits in+out)
|
||||
uint16_t fadeGamma(uint32_t channel, uint16_t v) {
|
||||
if (isChannelGammaCorrected(channel)) {
|
||||
@ -2106,7 +2117,9 @@ void LightSetOutputs(const uint16_t *cur_col_10) {
|
||||
if (pin[GPIO_PWM1 +i] < 99) {
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Cur_Col%d 10 bits %d"), i, cur_col_10[i]);
|
||||
uint16_t cur_col = cur_col_10[i + Light.pwm_offset];
|
||||
cur_col = cur_col > 0 ? changeUIntScale(cur_col, 0, Settings.pwm_range, Light.pwm_min, Light.pwm_max) : 0; // shrink to the range of pwm_min..pwm_max
|
||||
if (!isChannelCT(i)) { // if CT don't use pwm_min and pwm_max
|
||||
cur_col = cur_col > 0 ? changeUIntScale(cur_col, 0, Settings.pwm_range, Light.pwm_min, Light.pwm_max) : 0; // shrink to the range of pwm_min..pwm_max
|
||||
}
|
||||
analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col : cur_col);
|
||||
}
|
||||
}
|
||||
@ -2371,9 +2384,6 @@ bool LightColorEntry(char *buffer, uint32_t buffer_length)
|
||||
}
|
||||
} else {
|
||||
value = atoi(buffer);
|
||||
#ifdef USE_LIGHT_PALETTE
|
||||
value--;
|
||||
#endif // USE_LIGHT_PALETTE
|
||||
}
|
||||
#ifdef USE_LIGHT_PALETTE
|
||||
if (Light.palette_count) value = value % Light.palette_count;
|
||||
@ -2404,6 +2414,7 @@ bool LightColorEntry(char *buffer, uint32_t buffer_length)
|
||||
}
|
||||
#ifdef USE_LIGHT_PALETTE
|
||||
else if (Light.palette_count) {
|
||||
value--;
|
||||
Light.wheel = value;
|
||||
memcpy_P(&Light.entry_color, &Light.palette[value * LST_MAX], LST_MAX);
|
||||
entry_type = 1; // Hexadecimal
|
||||
|
@ -559,7 +559,7 @@ void HandleDomoticzConfiguration(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ);
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
DomoticzSaveSettings();
|
||||
WebRestart(1);
|
||||
return;
|
||||
@ -651,7 +651,7 @@ bool Xdrv07(uint8_t function)
|
||||
WSContentSend_P(HTTP_BTN_MENU_DOMOTICZ);
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration);
|
||||
Webserver->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
case FUNC_MQTT_SUBSCRIBE:
|
||||
|
@ -702,7 +702,7 @@ void HandleTimerConfiguration(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_TIMER);
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
TimerSaveSettings();
|
||||
HandleConfiguration();
|
||||
return;
|
||||
@ -740,7 +740,7 @@ void TimerSaveSettings(void)
|
||||
char message[LOGSZ];
|
||||
Timer timer;
|
||||
|
||||
Settings.flag3.timers_enable = WebServer->hasArg("e0"); // CMND_TIMERS
|
||||
Settings.flag3.timers_enable = Webserver->hasArg("e0"); // CMND_TIMERS
|
||||
WebGetArg("t0", tmp, sizeof(tmp));
|
||||
char *p = tmp;
|
||||
snprintf_P(message, sizeof(message), PSTR(D_LOG_MQTT D_CMND_TIMERS " %d"), Settings.flag3.timers_enable); // CMND_TIMERS
|
||||
@ -781,7 +781,7 @@ bool Xdrv09(uint8_t function)
|
||||
#endif // USE_RULES
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/" WEB_HANDLE_TIMER, HandleTimerConfiguration);
|
||||
Webserver->on("/" WEB_HANDLE_TIMER, HandleTimerConfiguration);
|
||||
break;
|
||||
#endif // USE_TIMERS_WEB
|
||||
#endif // USE_WEBSERVER
|
||||
|
@ -1797,8 +1797,11 @@ void CmndEvent(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
strlcpy(Rules.event_data, XdrvMailbox.data, sizeof(Rules.event_data));
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_EVENT, XdrvMailbox.data);
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
}
|
||||
ResponseCmndDone();
|
||||
if (XdrvMailbox.command) ResponseCmndDone();
|
||||
}
|
||||
|
||||
void CmndVariable(void)
|
||||
|
@ -65,6 +65,35 @@ keywords if then else endif, or, and are better readable for beginners (others m
|
||||
uint32_t EncodeLightId(uint8_t relay_id);
|
||||
uint32_t DecodeLightId(uint32_t hue_id);
|
||||
|
||||
#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)
|
||||
|
||||
#include "FS.h"
|
||||
#include "SPIFFS.h"
|
||||
void SaveFile(const char *name,const uint8_t *buf,uint32_t len) {
|
||||
File file = SPIFFS.open(name, FILE_WRITE);
|
||||
if (!file) return;
|
||||
file.write(buf, len);
|
||||
file.close();
|
||||
}
|
||||
|
||||
#define FORMAT_SPIFFS_IF_FAILED true
|
||||
uint8_t spiffs_mounted=0;
|
||||
|
||||
void LoadFile(const char *name,uint8_t *buf,uint32_t len) {
|
||||
if (!spiffs_mounted) {
|
||||
if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){
|
||||
//Serial.println("SPIFFS Mount Failed");
|
||||
return;
|
||||
}
|
||||
spiffs_mounted=1;
|
||||
}
|
||||
File file = SPIFFS.open(name);
|
||||
if (!file) return;
|
||||
file.read(buf, len);
|
||||
file.close();
|
||||
}
|
||||
#endif
|
||||
|
||||
// offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution
|
||||
#define EPOCH_OFFSET 1546300800
|
||||
|
||||
@ -3341,8 +3370,8 @@ void Script_FileUploadConfiguration(void)
|
||||
|
||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||
|
||||
if (WebServer->hasArg("download")) {
|
||||
String stmp = WebServer->arg("download");
|
||||
if (Webserver->hasArg("download")) {
|
||||
String stmp = Webserver->arg("download");
|
||||
char *cp=(char*)stmp.c_str();
|
||||
if (DownloadFile(cp)) {
|
||||
// is directory
|
||||
@ -3386,7 +3415,7 @@ void script_upload(void) {
|
||||
|
||||
//AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload"));
|
||||
|
||||
HTTPUpload& upload = WebServer->upload();
|
||||
HTTPUpload& upload = Webserver->upload();
|
||||
if (upload.status == UPLOAD_FILE_START) {
|
||||
char npath[48];
|
||||
sprintf(npath,"%s/%s",path,upload.filename.c_str());
|
||||
@ -3402,7 +3431,7 @@ void script_upload(void) {
|
||||
}
|
||||
} else {
|
||||
Web.upload_error=1;
|
||||
WebServer->send(500, "text/plain", "500: couldn't create file");
|
||||
Webserver->send(500, "text/plain", "500: couldn't create file");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3428,8 +3457,8 @@ uint8_t DownloadFile(char *file) {
|
||||
|
||||
uint32_t flen=download_file.size();
|
||||
|
||||
download_Client = WebServer->client();
|
||||
WebServer->setContentLength(flen);
|
||||
download_Client = Webserver->client();
|
||||
Webserver->setContentLength(flen);
|
||||
|
||||
char attachment[100];
|
||||
char *cp;
|
||||
@ -3440,7 +3469,7 @@ uint8_t DownloadFile(char *file) {
|
||||
}
|
||||
}
|
||||
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"),cp);
|
||||
WebServer->sendHeader(F("Content-Disposition"), attachment);
|
||||
Webserver->sendHeader(F("Content-Disposition"), attachment);
|
||||
WSSend(200, CT_STREAM, "");
|
||||
|
||||
uint8_t buff[512];
|
||||
@ -3472,7 +3501,7 @@ uint8_t DownloadFile(char *file) {
|
||||
void HandleScriptTextareaConfiguration(void) {
|
||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
ScriptSaveSettings();
|
||||
HandleConfiguration();
|
||||
return;
|
||||
@ -3486,13 +3515,13 @@ void HandleScriptConfiguration(void) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_SCRIPT);
|
||||
|
||||
#ifdef USE_SCRIPT_FATFS
|
||||
if (WebServer->hasArg("d1")) {
|
||||
if (Webserver->hasArg("d1")) {
|
||||
DownloadFile(glob_script_mem.flink[0]);
|
||||
}
|
||||
if (WebServer->hasArg("d2")) {
|
||||
if (Webserver->hasArg("d2")) {
|
||||
DownloadFile(glob_script_mem.flink[1]);
|
||||
}
|
||||
if (WebServer->hasArg("upl")) {
|
||||
if (Webserver->hasArg("upl")) {
|
||||
Script_FileUploadConfiguration();
|
||||
}
|
||||
#endif
|
||||
@ -3532,14 +3561,14 @@ void HandleScriptConfiguration(void) {
|
||||
|
||||
void ScriptSaveSettings(void) {
|
||||
|
||||
if (WebServer->hasArg("c1")) {
|
||||
if (Webserver->hasArg("c1")) {
|
||||
bitWrite(Settings.rule_enabled,0,1);
|
||||
} else {
|
||||
bitWrite(Settings.rule_enabled,0,0);
|
||||
}
|
||||
|
||||
|
||||
String str = WebServer->arg("t1");
|
||||
String str = Webserver->arg("t1");
|
||||
|
||||
if (*str.c_str()) {
|
||||
|
||||
@ -3597,6 +3626,11 @@ void ScriptSaveSettings(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)
|
||||
if (glob_script_mem.flags&1) {
|
||||
SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,ESP32_SCRIPT_SIZE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (glob_script_mem.script_mem) {
|
||||
@ -3990,11 +4024,11 @@ void Script_Handle_Hue(String *path) {
|
||||
uint8_t device = DecodeLightId(atoi(path->c_str()));
|
||||
uint8_t index = device-devices_present-1;
|
||||
|
||||
if (WebServer->args()) {
|
||||
if (Webserver->args()) {
|
||||
response = "[";
|
||||
|
||||
StaticJsonBuffer<400> jsonBuffer;
|
||||
JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1));
|
||||
JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1));
|
||||
if (hue_json.containsKey("on")) {
|
||||
|
||||
response += FPSTR(sHUE_LIGHT_RESPONSE_JSON);
|
||||
@ -4436,8 +4470,8 @@ void Script_Check_HTML_Setvars(void) {
|
||||
|
||||
if (!HttpCheckPriviledgedAccess()) { return; }
|
||||
|
||||
if (WebServer->hasArg("sv")) {
|
||||
String stmp = WebServer->arg("sv");
|
||||
if (Webserver->hasArg("sv")) {
|
||||
String stmp = Webserver->arg("sv");
|
||||
char cmdbuf[64];
|
||||
memset(cmdbuf,0,sizeof(cmdbuf));
|
||||
char *cp=cmdbuf;
|
||||
@ -4820,6 +4854,13 @@ bool Xdrv10(uint8_t function)
|
||||
|
||||
switch (function) {
|
||||
case FUNC_PRE_INIT:
|
||||
/*
|
||||
#ifdef USE_WEBCAM
|
||||
if (Settings.module==ESP32_CAM_AITHINKER) {
|
||||
webcam_setup();
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
// set defaults to rules memory
|
||||
glob_script_mem.script_ram=Settings.rules[0];
|
||||
glob_script_mem.script_size=MAX_SCRIPT_SIZE;
|
||||
@ -4889,6 +4930,21 @@ bool Xdrv10(uint8_t function)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)
|
||||
char *script;
|
||||
script=(char*)calloc(ESP32_SCRIPT_SIZE+4,1);
|
||||
if (!script) break;
|
||||
LoadFile("/script.txt",(uint8_t*)script,ESP32_SCRIPT_SIZE);
|
||||
glob_script_mem.script_ram=script;
|
||||
glob_script_mem.script_size=ESP32_SCRIPT_SIZE;
|
||||
script[ESP32_SCRIPT_SIZE-1]=0;
|
||||
// use rules storage for permanent vars
|
||||
glob_script_mem.script_pram=(uint8_t*)Settings.rules[0];
|
||||
glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE;
|
||||
glob_script_mem.flags=1;
|
||||
#endif
|
||||
|
||||
// assure permanent memory is 4 byte aligned
|
||||
{ uint32_t ptr=(uint32_t)glob_script_mem.script_pram;
|
||||
ptr&=0xfffffffc;
|
||||
@ -4932,13 +4988,13 @@ bool Xdrv10(uint8_t function)
|
||||
WSContentSend_P(HTTP_BTN_MENU_RULES);
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration);
|
||||
WebServer->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration);
|
||||
Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration);
|
||||
Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration);
|
||||
|
||||
#ifdef USE_SCRIPT_FATFS
|
||||
WebServer->on("/u3", HTTP_POST,[]() { WebServer->sendHeader("Location","/u3");WebServer->send(303);},script_upload);
|
||||
WebServer->on("/u3", HTTP_GET,ScriptFileUploadSuccess);
|
||||
WebServer->on("/upl", HTTP_GET,Script_FileUploadConfiguration);
|
||||
Webserver->on("/u3", HTTP_POST,[]() { Webserver->sendHeader("Location","/u3");Webserver->send(303);},script_upload);
|
||||
Webserver->on("/u3", HTTP_GET,ScriptFileUploadSuccess);
|
||||
Webserver->on("/upl", HTTP_GET,Script_FileUploadConfiguration);
|
||||
#endif
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
|
@ -809,22 +809,22 @@ void HandleKNXConfiguration(void)
|
||||
char tmp[100];
|
||||
String stmp;
|
||||
|
||||
if ( WebServer->hasArg("save") ) {
|
||||
if ( Webserver->hasArg("save") ) {
|
||||
KNX_Save_Settings();
|
||||
HandleConfiguration();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( WebServer->hasArg("btn_add") ) {
|
||||
if ( WebServer->arg("btn_add") == "1" ) {
|
||||
if ( Webserver->hasArg("btn_add") ) {
|
||||
if ( Webserver->arg("btn_add") == "1" ) {
|
||||
|
||||
stmp = WebServer->arg("GAop"); //option selected
|
||||
stmp = Webserver->arg("GAop"); //option selected
|
||||
uint8_t GAop = stmp.toInt();
|
||||
stmp = WebServer->arg("GA_FNUM");
|
||||
stmp = Webserver->arg("GA_FNUM");
|
||||
uint8_t GA_FNUM = stmp.toInt();
|
||||
stmp = WebServer->arg("GA_AREA");
|
||||
stmp = Webserver->arg("GA_AREA");
|
||||
uint8_t GA_AREA = stmp.toInt();
|
||||
stmp = WebServer->arg("GA_FDEF");
|
||||
stmp = Webserver->arg("GA_FDEF");
|
||||
uint8_t GA_FDEF = stmp.toInt();
|
||||
|
||||
if (GAop) {
|
||||
@ -834,13 +834,13 @@ void HandleKNXConfiguration(void)
|
||||
else
|
||||
{
|
||||
|
||||
stmp = WebServer->arg("CBop"); //option selected
|
||||
stmp = Webserver->arg("CBop"); //option selected
|
||||
uint8_t CBop = stmp.toInt();
|
||||
stmp = WebServer->arg("CB_FNUM");
|
||||
stmp = Webserver->arg("CB_FNUM");
|
||||
uint8_t CB_FNUM = stmp.toInt();
|
||||
stmp = WebServer->arg("CB_AREA");
|
||||
stmp = Webserver->arg("CB_AREA");
|
||||
uint8_t CB_AREA = stmp.toInt();
|
||||
stmp = WebServer->arg("CB_FDEF");
|
||||
stmp = Webserver->arg("CB_FDEF");
|
||||
uint8_t CB_FDEF = stmp.toInt();
|
||||
|
||||
if (CBop) {
|
||||
@ -848,19 +848,19 @@ void HandleKNXConfiguration(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( WebServer->hasArg("btn_del_ga") )
|
||||
else if ( Webserver->hasArg("btn_del_ga") )
|
||||
{
|
||||
|
||||
stmp = WebServer->arg("btn_del_ga");
|
||||
stmp = Webserver->arg("btn_del_ga");
|
||||
uint8_t GA_NUM = stmp.toInt();
|
||||
|
||||
KNX_DEL_GA(GA_NUM);
|
||||
|
||||
}
|
||||
else if ( WebServer->hasArg("btn_del_cb") )
|
||||
else if ( Webserver->hasArg("btn_del_cb") )
|
||||
{
|
||||
|
||||
stmp = WebServer->arg("btn_del_cb");
|
||||
stmp = Webserver->arg("btn_del_cb");
|
||||
uint8_t CB_NUM = stmp.toInt();
|
||||
|
||||
KNX_DEL_CB(CB_NUM);
|
||||
@ -954,16 +954,16 @@ void KNX_Save_Settings(void)
|
||||
String stmp;
|
||||
address_t KNX_addr;
|
||||
|
||||
Settings.flag.knx_enabled = WebServer->hasArg("b1");
|
||||
Settings.flag.knx_enable_enhancement = WebServer->hasArg("b2");
|
||||
Settings.flag.knx_enabled = Webserver->hasArg("b1");
|
||||
Settings.flag.knx_enable_enhancement = Webserver->hasArg("b2");
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_KNX D_ENABLED ": %d, " D_KNX_ENHANCEMENT ": %d"),
|
||||
Settings.flag.knx_enabled, Settings.flag.knx_enable_enhancement );
|
||||
|
||||
stmp = WebServer->arg("area");
|
||||
stmp = Webserver->arg("area");
|
||||
KNX_addr.pa.area = stmp.toInt();
|
||||
stmp = WebServer->arg("line");
|
||||
stmp = Webserver->arg("line");
|
||||
KNX_addr.pa.line = stmp.toInt();
|
||||
stmp = WebServer->arg("member");
|
||||
stmp = Webserver->arg("member");
|
||||
KNX_addr.pa.member = stmp.toInt();
|
||||
Settings.knx_physsical_addr = KNX_addr.value;
|
||||
knx.physical_address_set( KNX_addr ); // Set Physical KNX Address of the device
|
||||
@ -1224,7 +1224,7 @@ bool Xdrv11(uint8_t function)
|
||||
WSContentSend_P(HTTP_BTN_MENU_KNX);
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/kn", HandleKNXConfiguration);
|
||||
Webserver->on("/kn", HandleKNXConfiguration);
|
||||
break;
|
||||
#endif // USE_KNX_WEB_MENU
|
||||
#endif // USE_WEBSERVER
|
||||
|
@ -448,7 +448,7 @@ static const char * FIRST_GEN_UA[] = { // list of User-Agents signature
|
||||
// Check if the Echo device is of 1st generation, which triggers different results
|
||||
uint32_t findEchoGeneration(void) {
|
||||
// result is 1 for 1st gen, 2 for 2nd gen and further
|
||||
String user_agent = WebServer->header("User-Agent");
|
||||
String user_agent = Webserver->header("User-Agent");
|
||||
uint32_t gen = 2;
|
||||
|
||||
for (uint32_t i = 0; i < sizeof(FIRST_GEN_UA)/sizeof(char*); i++) {
|
||||
@ -521,11 +521,11 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
|
||||
const size_t buf_size = 100;
|
||||
char * buf = (char*) malloc(buf_size);
|
||||
|
||||
if (WebServer->args()) {
|
||||
if (Webserver->args()) {
|
||||
response = "[";
|
||||
|
||||
StaticJsonBuffer<300> jsonBuffer;
|
||||
JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1));
|
||||
JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1));
|
||||
if (hue_json.containsKey("on")) {
|
||||
on = hue_json["on"];
|
||||
snprintf_P(buf, buf_size,
|
||||
@ -542,6 +542,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
/*
|
||||
switch(on)
|
||||
{
|
||||
case false : ExecuteCommandPower(device, POWER_OFF, SRC_HUE);
|
||||
@ -549,6 +550,8 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) {
|
||||
case true : ExecuteCommandPower(device, POWER_ON, SRC_HUE);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
ExecuteCommandPower(device, (on) ? POWER_ON : POWER_OFF, SRC_HUE);
|
||||
response += buf;
|
||||
resp = true;
|
||||
#ifdef USE_SHUTTER
|
||||
@ -827,8 +830,8 @@ void HandleHueApi(String *path)
|
||||
path->remove(0, 4); // remove /api
|
||||
uint16_t apilen = path->length();
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_API " (%s)"), path->c_str()); // HTP: Hue API (//lights/1/state
|
||||
for (args = 0; args < WebServer->args(); args++) {
|
||||
String json = WebServer->arg(args);
|
||||
for (args = 0; args < Webserver->args(); args++) {
|
||||
String json = Webserver->arg(args);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_POST_ARGS " (%s)"), json.c_str()); // HTP: Hue POST args ({"on":false})
|
||||
}
|
||||
|
||||
@ -861,7 +864,7 @@ bool Xdrv20(uint8_t function)
|
||||
#endif
|
||||
switch (function) {
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on(F("/description.xml"), HandleUpnpSetupHue);
|
||||
Webserver->on(F("/description.xml"), HandleUpnpSetupHue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ void HandleUpnpEvent(void)
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT));
|
||||
|
||||
char event[500];
|
||||
strlcpy(event, WebServer->arg(0).c_str(), sizeof(event));
|
||||
strlcpy(event, Webserver->arg(0).c_str(), sizeof(event));
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), event);
|
||||
|
||||
@ -259,10 +259,10 @@ bool Xdrv21(uint8_t function)
|
||||
if (devices_present && (EMUL_WEMO == Settings.flag2.emulation)) {
|
||||
switch (function) {
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent);
|
||||
WebServer->on("/eventservice.xml", HandleUpnpService);
|
||||
WebServer->on("/metainfoservice.xml", HandleUpnpMetaService);
|
||||
WebServer->on("/setup.xml", HandleUpnpSetupWemo);
|
||||
Webserver->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent);
|
||||
Webserver->on("/eventservice.xml", HandleUpnpService);
|
||||
Webserver->on("/metainfoservice.xml", HandleUpnpMetaService);
|
||||
Webserver->on("/setup.xml", HandleUpnpSetupWemo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -25,15 +25,15 @@ void ZigbeeZCLSend_Raw(uint16_t dtsAddr, uint16_t groupaddr, uint16_t clusterId,
|
||||
|
||||
|
||||
// Get an JSON attribute, with case insensitive key search
|
||||
JsonVariant &getCaseInsensitive(const JsonObject &json, const char *needle) {
|
||||
const JsonVariant &getCaseInsensitive(const JsonObject &json, const char *needle) {
|
||||
// key can be in PROGMEM
|
||||
if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle))) {
|
||||
return *(JsonVariant*)nullptr;
|
||||
}
|
||||
|
||||
for (auto kv : json) {
|
||||
const char *key = kv.key;
|
||||
JsonVariant &value = kv.value;
|
||||
for (JsonObject::const_iterator it=json.begin(); it!=json.end(); ++it) {
|
||||
const char *key = it->key;
|
||||
const JsonVariant &value = it->value;
|
||||
|
||||
if (0 == strcasecmp_P(key, needle)) {
|
||||
return value;
|
||||
|
@ -65,7 +65,7 @@ typedef int32_t (*Z_DeviceTimer)(uint16_t shortaddr, uint16_t groupaddr, uint16_
|
||||
typedef enum Z_Def_Category {
|
||||
Z_CAT_NONE = 0, // no category, it will happen anyways
|
||||
Z_CAT_READ_ATTR, // Attribute reporting, either READ_ATTRIBUTE or REPORT_ATTRIBUTE, we coalesce all attributes reported if we can
|
||||
Z_CAT_VIRTUAL_ATTR, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor
|
||||
Z_CAT_VIRTUAL_OCCUPANCY, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor
|
||||
Z_CAT_REACHABILITY, // timer set to measure reachability of device, i.e. if we don't get an answer after 1s, it is marked as unreachable (for Alexa)
|
||||
Z_CAT_READ_0006, // Read 0x0006 cluster
|
||||
Z_CAT_READ_0008, // Read 0x0008 cluster
|
||||
|
@ -190,23 +190,21 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
|
||||
const size_t buf_size = 100;
|
||||
char * buf = (char*) malloc(buf_size);
|
||||
|
||||
if (WebServer->args()) {
|
||||
if (Webserver->args()) {
|
||||
response = "[";
|
||||
|
||||
StaticJsonBuffer<300> jsonBuffer;
|
||||
JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1));
|
||||
JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1));
|
||||
if (hue_json.containsKey("on")) {
|
||||
on = hue_json["on"];
|
||||
snprintf_P(buf, buf_size,
|
||||
PSTR("{\"success\":{\"/lights/%d/state/on\":%s}}"),
|
||||
device_id, on ? "true" : "false");
|
||||
|
||||
switch(on)
|
||||
{
|
||||
case false : ZigbeeHuePower(shortaddr, 0x00);
|
||||
break;
|
||||
case true : ZigbeeHuePower(shortaddr, 0x01);
|
||||
break;
|
||||
if (on) {
|
||||
ZigbeeHuePower(shortaddr, 0x01);
|
||||
} else {
|
||||
ZigbeeHuePower(shortaddr, 0x00);
|
||||
}
|
||||
response += buf;
|
||||
resp = true;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,7 @@ ZF(DimmerMove) ZF(DimmerStep)
|
||||
ZF(HueMove) ZF(HueStep) ZF(SatMove) ZF(SatStep) ZF(ColorMove) ZF(ColorStep)
|
||||
ZF(ArrowClick) ZF(ArrowHold) ZF(ArrowRelease) ZF(ZoneStatusChange)
|
||||
|
||||
ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(001902) ZF(011902) ZF(xxyyyy) ZF(xx)
|
||||
ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(00190200) ZF(01190200) ZF(xxyyyy) ZF(xx)
|
||||
ZF(xx000A00) ZF(xx0A00) ZF(xxyy0A00) ZF(xxxxyyyy0A00) ZF(xxxx0A00) ZF(xx0A)
|
||||
ZF(xx190A00) ZF(xx19) ZF(xx190A) ZF(xxxxyyyy) ZF(xxxxyyzz) ZF(xxyyzzzz) ZF(xxyyyyzz)
|
||||
|
||||
@ -82,8 +82,8 @@ const Z_CommandConverter Z_Commands[] PROGMEM = {
|
||||
// Light & Shutter commands
|
||||
{ Z(Power), 0x0006, 0xFF, 0x01, Z() }, // 0=Off, 1=On, 2=Toggle
|
||||
{ Z(Dimmer), 0x0008, 0x04, 0x01, Z(xx0A00) }, // Move to Level with On/Off, xx=0..254 (255 is invalid)
|
||||
{ Z(DimmerUp), 0x0008, 0x06, 0x01, Z(001902) }, // Step up by 10%, 0.2 secs
|
||||
{ Z(DimmerDown), 0x0008, 0x06, 0x01, Z(011902) }, // Step down by 10%, 0.2 secs
|
||||
{ Z(DimmerUp), 0x0008, 0x06, 0x01, Z(00190200) }, // Step up by 10%, 0.2 secs
|
||||
{ Z(DimmerDown), 0x0008, 0x06, 0x01, Z(01190200) }, // Step down by 10%, 0.2 secs
|
||||
{ Z(DimmerStop), 0x0008, 0x03, 0x01, Z() }, // Stop any Dimmer animation
|
||||
{ Z(ResetAlarm), 0x0009, 0x00, 0x01, Z(xxyyyy) }, // Reset alarm (alarm code + cluster identifier)
|
||||
{ Z(ResetAllAlarms), 0x0009, 0x01, 0x01, Z() }, // Reset all alarms
|
||||
|
@ -534,7 +534,9 @@ void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, co
|
||||
uint32_t occupancy = strToUInt(val_endpoint);
|
||||
|
||||
if (occupancy) {
|
||||
zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_ATTR, 0, &Z_OccupancyCallback);
|
||||
zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback);
|
||||
} else {
|
||||
zigbee_devices.resetTimersForDevice(shortaddr, 0 /* groupaddr */, Z_CAT_VIRTUAL_OCCUPANCY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ void HandlePcf8574(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_PCF8574));
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
Pcf8574SaveSettings();
|
||||
WebRestart(1);
|
||||
return;
|
||||
@ -193,9 +193,9 @@ void Pcf8574SaveSettings(void)
|
||||
char stemp[7];
|
||||
char tmp[100];
|
||||
|
||||
//AddLog_P(LOG_LEVEL_DEBUG, PSTR("PCF: Start working on Save arguements: inverted:%d")), WebServer->hasArg("b1");
|
||||
//AddLog_P(LOG_LEVEL_DEBUG, PSTR("PCF: Start working on Save arguements: inverted:%d")), Webserver->hasArg("b1");
|
||||
|
||||
Settings.flag3.pcf8574_ports_inverted = WebServer->hasArg("b1"); // SetOption81 - Invert all ports on PCF8574 devices
|
||||
Settings.flag3.pcf8574_ports_inverted = Webserver->hasArg("b1"); // SetOption81 - Invert all ports on PCF8574 devices
|
||||
for (byte idx = 0; idx < Pcf8574.max_devices; idx++) {
|
||||
byte count=0;
|
||||
byte n = Settings.pcf8574_config[idx];
|
||||
@ -248,7 +248,7 @@ bool Xdrv28(uint8_t function)
|
||||
WSContentSend_P(HTTP_BTN_MENU_PCF8574);
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/" WEB_HANDLE_PCF8574, HandlePcf8574);
|
||||
Webserver->on("/" WEB_HANDLE_PCF8574, HandlePcf8574);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ void (* const PWMDimmerCommand[])(void) PROGMEM = {
|
||||
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
struct remote_pwm_dimmer {
|
||||
power_t power;
|
||||
bool power_on;
|
||||
uint8_t bri_power_on;
|
||||
uint8_t bri_preset_low;
|
||||
uint8_t bri_preset_high;
|
||||
@ -178,7 +178,7 @@ void PWMDimmerHandleDevGroupItem(void)
|
||||
uint8_t device_group_index = *(uint8_t *)XdrvMailbox.topic;
|
||||
if (device_group_index > remote_pwm_dimmer_count) return;
|
||||
bool device_is_local = device_groups[device_group_index].local;
|
||||
struct remote_pwm_dimmer * remote_pwm_dimmer = &remote_pwm_dimmers[device_group_index];
|
||||
struct remote_pwm_dimmer * remote_pwm_dimmer = &remote_pwm_dimmers[device_group_index - 1];
|
||||
#else // USE_PWM_DIMMER_REMOTE
|
||||
if (*(uint8_t *)XdrvMailbox.topic) return;
|
||||
#endif // !USE_PWM_DIMMER_REMOTE
|
||||
@ -190,7 +190,7 @@ void PWMDimmerHandleDevGroupItem(void)
|
||||
break;
|
||||
case DGR_ITEM_POWER:
|
||||
if (!device_is_local) {
|
||||
remote_pwm_dimmer->power = value;
|
||||
remote_pwm_dimmer->power_on = value & 1;
|
||||
remote_pwm_dimmer->power_button_increases_bri = (remote_pwm_dimmer->bri < 128);
|
||||
}
|
||||
break;
|
||||
@ -286,7 +286,7 @@ void PWMDimmerHandleButton(void)
|
||||
|
||||
// Initialize some variables.
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
bool power_is_on = (!active_device_is_local ? active_remote_pwm_dimmer->power : power);
|
||||
bool power_is_on = (!active_device_is_local ? active_remote_pwm_dimmer->power_on : power);
|
||||
bool is_power_button = (button_index == power_button_index);
|
||||
#else // USE_PWM_DIMMER_REMOTE
|
||||
bool power_is_on = power;
|
||||
@ -344,8 +344,9 @@ void PWMDimmerHandleButton(void)
|
||||
// If this is about the power button, ...
|
||||
if (is_power_button) {
|
||||
|
||||
// If no other buttons are pressed, ...
|
||||
if (buttons_pressed == 1) {
|
||||
// If no other buttons are pressed and the up or down button was tapped while holding the
|
||||
// power button before this, ...
|
||||
if (buttons_pressed == 1 && !tap_count) {
|
||||
|
||||
// If the power is on, adjust the brightness. Set the direction based on the current
|
||||
// direction for the device and then invert the direction when the power button is
|
||||
@ -628,8 +629,8 @@ void PWMDimmerHandleButton(void)
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
#ifdef USE_PWM_DIMMER_REMOTE
|
||||
if (!active_device_is_local) {
|
||||
active_remote_pwm_dimmer->power ^= 1;
|
||||
new_power = active_remote_pwm_dimmer->power;
|
||||
active_remote_pwm_dimmer->power_on ^= 1;
|
||||
new_power = active_remote_pwm_dimmer->power_on;
|
||||
}
|
||||
else {
|
||||
#endif // USE_PWM_DIMMER_REMOTE
|
||||
|
@ -21,7 +21,10 @@
|
||||
|
||||
#define XDRV_38 38
|
||||
|
||||
#include <ping.h>
|
||||
#include "lwip/icmp.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/raw.h"
|
||||
#include "lwip/timeouts.h"
|
||||
|
||||
const char kPingCommands[] PROGMEM = "|" // no prefix
|
||||
D_CMND_PING
|
||||
@ -31,119 +34,291 @@ void (* const PingCommand[])(void) PROGMEM = {
|
||||
&CmndPing,
|
||||
};
|
||||
|
||||
// inspired by https://github.com/dancol90/ESP8266Ping
|
||||
|
||||
typedef struct Ping_t {
|
||||
uint16_t total_count; // total count if packets sent
|
||||
uint16_t timeout_count; // time-outs (no responses)
|
||||
uint32_t min_time; // minimum time in ms for a successful response
|
||||
uint32_t max_time; // maximum time in ms for a successful response
|
||||
uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average)
|
||||
bool busy; // is ping on-going
|
||||
bool done; // indicates the ping campaign is finished
|
||||
} Ping_t;
|
||||
|
||||
ping_option ping_opt;
|
||||
Ping_t ping;
|
||||
|
||||
extern "C" {
|
||||
// callbacks for ping
|
||||
|
||||
extern uint32 system_relative_time(uint32 time);
|
||||
extern void ets_bzero(void *s, size_t n);
|
||||
|
||||
// called after a ping response is received or time-out
|
||||
void ICACHE_RAM_ATTR ping_recv_cb(ping_option *popt, struct ping_resp *p_resp) {
|
||||
// If successful
|
||||
if (p_resp->ping_err >= 0) {
|
||||
uint32_t resp_time = p_resp->resp_time;
|
||||
ping.sum_time += resp_time;
|
||||
if (resp_time < ping.min_time) { ping.min_time = resp_time; }
|
||||
if (resp_time > ping.max_time) { ping.max_time = resp_time; }
|
||||
const uint16_t Ping_ID = 0xAFAF; // PING packet ID
|
||||
const size_t Ping_data_size = 32; // default packet size
|
||||
const uint32_t Ping_timeout_ms = 1000; // default time-out of 1 second, which is enough for LAN/WIFI
|
||||
const uint32_t Ping_coarse = 1000; // interval between sending packets, 1 packet every second
|
||||
|
||||
typedef struct Ping_t {
|
||||
uint32 ip; // target IPv4 address
|
||||
Ping_t *next; // next object in linked list
|
||||
uint16_t seq_num; // next sequence number
|
||||
uint16_t seqno; // reject a packet already received
|
||||
uint8_t success_count; // sucessful responses received
|
||||
uint8_t timeout_count; // time-outs (no responses)
|
||||
uint8_t to_send_count; // number of packets remaining to send
|
||||
uint32_t ping_time_sent; // timestamp when the packet was sent
|
||||
uint32_t min_time; // minimum time in ms for a successful response
|
||||
uint32_t max_time; // maximum time in ms for a successful response
|
||||
uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average)
|
||||
bool done; // indicates the ping campaign is finished
|
||||
bool fast; // fast mode, i.e. stop pings when first successful response
|
||||
} Ping_t;
|
||||
|
||||
// globals
|
||||
Ping_t *ping_head = nullptr; // head of the Linked List for ping objects
|
||||
struct raw_pcb *t_ping_pcb = nullptr; // registered with first ping, deregistered after last ping, the same pcb is used for all packets
|
||||
|
||||
// ================================================================================
|
||||
// Find the Ping object indexed by IP address
|
||||
// ================================================================================
|
||||
//
|
||||
// find the ping structure corresponding to the specified IP, or nullptr if not found
|
||||
//
|
||||
Ping_t ICACHE_FLASH_ATTR * t_ping_find(uint32_t ip) {
|
||||
Ping_t *ping = ping_head;
|
||||
while (ping != nullptr) {
|
||||
if (ping->ip == ip) {
|
||||
return ping;
|
||||
}
|
||||
ping = ping->next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
// Timer called a packet response is in time-out
|
||||
// ================================================================================
|
||||
//
|
||||
// called after the ICMP timeout occured
|
||||
// we never received the packet, increase the timeout count
|
||||
//
|
||||
void ICACHE_FLASH_ATTR t_ping_timeout(void* arg) {
|
||||
Ping_t *ping = (Ping_t*) arg;
|
||||
ping->timeout_count++;
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
// Send ICMP packet
|
||||
// ================================================================================
|
||||
// Prepare a echo ICMP request
|
||||
//
|
||||
void ICACHE_FLASH_ATTR t_ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_t len, Ping_t *ping) {
|
||||
size_t data_len = len - sizeof(struct icmp_echo_hdr);
|
||||
|
||||
ICMPH_TYPE_SET(iecho, ICMP_ECHO);
|
||||
ICMPH_CODE_SET(iecho, 0);
|
||||
iecho->chksum = 0;
|
||||
iecho->id = Ping_ID;
|
||||
ping->seq_num++;
|
||||
if (ping->seq_num == 0x7fff) { ping->seq_num = 0; }
|
||||
|
||||
iecho->seqno = htons(ping->seq_num); // TODO
|
||||
|
||||
/* fill the additional data buffer with some data */
|
||||
for (uint32_t i = 0; i < data_len; i++) {
|
||||
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
|
||||
}
|
||||
|
||||
iecho->chksum = inet_chksum(iecho, len);
|
||||
}
|
||||
//
|
||||
// send the ICMP packet
|
||||
//
|
||||
void ICACHE_FLASH_ATTR t_ping_send(struct raw_pcb *raw, Ping_t *ping) {
|
||||
struct pbuf *p;
|
||||
uint16_t ping_size = sizeof(struct icmp_echo_hdr) + Ping_data_size;
|
||||
|
||||
ping->ping_time_sent = system_get_time();
|
||||
p = pbuf_alloc(PBUF_IP, ping_size, PBUF_RAM);
|
||||
if (!p) { return; }
|
||||
if ((p->len == p->tot_len) && (p->next == nullptr)) {
|
||||
ip_addr_t ping_target;
|
||||
struct icmp_echo_hdr *iecho;
|
||||
|
||||
ping_target.addr = ping->ip;
|
||||
iecho = (struct icmp_echo_hdr *) p->payload;
|
||||
|
||||
t_ping_prepare_echo(iecho, ping_size, ping);
|
||||
raw_sendto(raw, p, &ping_target);
|
||||
}
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
// Timer called when it's time to send next packet, of when finished
|
||||
// ================================================================================
|
||||
// this timer is called every x seconds to send a new packet, whatever happened to the previous packet
|
||||
static void ICACHE_FLASH_ATTR t_ping_coarse_tmr(void *arg) {
|
||||
Ping_t *ping = (Ping_t*) arg;
|
||||
if (ping->to_send_count > 0) {
|
||||
ping->to_send_count--;
|
||||
// have we sent all packets?
|
||||
t_ping_send(t_ping_pcb, ping);
|
||||
|
||||
sys_timeout(Ping_timeout_ms, t_ping_timeout, ping);
|
||||
sys_timeout(Ping_coarse, t_ping_coarse_tmr, ping);
|
||||
} else {
|
||||
sys_untimeout(t_ping_coarse_tmr, ping);
|
||||
ping->done = true;
|
||||
}
|
||||
}
|
||||
|
||||
// called after the ping campaign is finished
|
||||
void ICACHE_RAM_ATTR ping_sent_cb(ping_option *popt, struct ping_resp *p_resp) {
|
||||
// copy counters to build the MQTT response
|
||||
ping.total_count = p_resp->total_count;
|
||||
ping.timeout_count = p_resp->timeout_count;
|
||||
ping.done = true;
|
||||
// ================================================================================
|
||||
// Callback: a packet response was received
|
||||
// ================================================================================
|
||||
//
|
||||
// Reveived packet
|
||||
//
|
||||
static uint8_t ICACHE_FLASH_ATTR t_ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) {
|
||||
Ping_t *ping = t_ping_find(addr->addr);
|
||||
|
||||
if (nullptr == ping) { // unknown source address
|
||||
return 0; // don't eat the packet and ignore it
|
||||
}
|
||||
|
||||
if (pbuf_header( p, -PBUF_IP_HLEN)==0) {
|
||||
struct icmp_echo_hdr *iecho;
|
||||
iecho = (struct icmp_echo_hdr *)p->payload;
|
||||
|
||||
if ((iecho->id == Ping_ID) && (iecho->seqno == htons(ping->seq_num)) && iecho->type == ICMP_ER) {
|
||||
|
||||
if (iecho->seqno != ping->seqno){ // debounce already received packet
|
||||
/* do some ping result processing */
|
||||
sys_untimeout(t_ping_timeout, ping); // remove time-out handler
|
||||
uint32_t delay = system_relative_time(ping->ping_time_sent);
|
||||
delay /= 1000;
|
||||
|
||||
ping->sum_time += delay;
|
||||
if (delay < ping->min_time) { ping->min_time = delay; }
|
||||
if (delay > ping->max_time) { ping->max_time = delay; }
|
||||
|
||||
ping->success_count++;
|
||||
ping->seqno = iecho->seqno;
|
||||
if (ping->fast) { // if fast mode, abort further pings when first successful response is received
|
||||
sys_untimeout(t_ping_coarse_tmr, ping);
|
||||
ping->done = true;
|
||||
ping->to_send_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
return 1; /* eat the packet */
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* don't eat the packet */
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
// Internal structure PCB management
|
||||
// ================================================================================
|
||||
// we are going to send a packet, make sure pcb is initialized
|
||||
void t_ping_register_pcb(void) {
|
||||
if (nullptr == t_ping_pcb) {
|
||||
t_ping_pcb = raw_new(IP_PROTO_ICMP);
|
||||
|
||||
raw_recv(t_ping_pcb, t_ping_recv, nullptr); // we cannot register data structure here as we can only register one
|
||||
raw_bind(t_ping_pcb, IP_ADDR_ANY);
|
||||
}
|
||||
}
|
||||
|
||||
// we have finsihed a ping series, deallocated if no more ongoing
|
||||
void t_ping_deregister_pcb(void) {
|
||||
if (nullptr == ping_head) { // deregister only if no ping is flying
|
||||
raw_remove(t_ping_pcb);
|
||||
t_ping_pcb = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
// Start pings
|
||||
// ================================================================================
|
||||
bool t_ping_start(uint32_t ip, uint32_t count) {
|
||||
// check if pings are already ongoing for this IP
|
||||
if (t_ping_find(ip)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Ping_t *ping = new Ping_t();
|
||||
if (0 == count) {
|
||||
count = 4;
|
||||
ping->fast = true;
|
||||
}
|
||||
ping->min_time = UINT32_MAX;
|
||||
ping->ip = ip;
|
||||
ping->to_send_count = count - 1;
|
||||
|
||||
// add to Linked List from head
|
||||
ping->next = ping_head;
|
||||
ping_head = ping; // insert at head
|
||||
|
||||
t_ping_register_pcb();
|
||||
t_ping_send(t_ping_pcb, ping);
|
||||
|
||||
// set timers for time-out and cadence
|
||||
sys_timeout(Ping_timeout_ms, t_ping_timeout, ping);
|
||||
sys_timeout(Ping_coarse, t_ping_coarse_tmr, ping);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check if any ping requests is completed, and publish the results
|
||||
void PingResponsePoll(void) {
|
||||
if (ping.done) {
|
||||
uint32_t success = ping.total_count - ping.timeout_count;
|
||||
uint32_t ip = ping_opt.ip;
|
||||
Ping_t *ping = ping_head;
|
||||
Ping_t **prev_link = &ping_head; // previous link pointer (used to remove en entry)
|
||||
|
||||
// Serial.printf(
|
||||
// "DEBUG ping_sent_cb: ping reply\n"
|
||||
// "\tsuccess_count = %d \n"
|
||||
// "\ttimeout_count = %d \n"
|
||||
// "\tmin_time = %d \n"
|
||||
// "\tmax_time = %d \n"
|
||||
// "\tavg_time = %d \n",
|
||||
// success, ping.timeout_count,
|
||||
// ping.min_time, ping.max_time,
|
||||
// success ? ping.sum_time / success : 0
|
||||
// );
|
||||
while (ping != nullptr) {
|
||||
if (ping->done) {
|
||||
uint32_t success = ping->success_count;
|
||||
uint32_t ip = ping->ip;
|
||||
|
||||
Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{"
|
||||
"\"Reachable\":%s"
|
||||
",\"Success\":%d"
|
||||
",\"Timeout\":%d"
|
||||
",\"MinTime\":%d"
|
||||
",\"MaxTime\":%d"
|
||||
",\"AvgTime\":%d"
|
||||
"}}}"),
|
||||
ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24,
|
||||
success ? "true" : "false",
|
||||
success, ping.timeout_count,
|
||||
ping.min_time, ping.max_time,
|
||||
success ? ping.sum_time / success : 0
|
||||
);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING));
|
||||
XdrvRulesProcess();
|
||||
ping.done = false;
|
||||
ping.busy = false;
|
||||
Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{"
|
||||
"\"Reachable\":%s"
|
||||
",\"Success\":%d"
|
||||
",\"Timeout\":%d"
|
||||
",\"MinTime\":%d"
|
||||
",\"MaxTime\":%d"
|
||||
",\"AvgTime\":%d"
|
||||
"}}}"),
|
||||
ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24,
|
||||
success ? "true" : "false",
|
||||
success, ping->timeout_count,
|
||||
success ? ping->min_time : 0, ping->max_time,
|
||||
success ? ping->sum_time / success : 0
|
||||
);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING));
|
||||
XdrvRulesProcess();
|
||||
|
||||
// remove from linked list
|
||||
*prev_link = ping->next;
|
||||
// don't increment prev_link
|
||||
Ping_t *ping_to_delete = ping;
|
||||
ping = ping->next; // move to next before deleting the object
|
||||
delete ping_to_delete; // free memory allocated
|
||||
} else {
|
||||
prev_link = &ping->next;
|
||||
ping = ping->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Ping Command
|
||||
\*********************************************************************************************/
|
||||
|
||||
void CmndPing(void) {
|
||||
uint32_t count = XdrvMailbox.index;
|
||||
IPAddress ip;
|
||||
|
||||
RemoveSpace(XdrvMailbox.data);
|
||||
if (count > 8) { count = 8; }
|
||||
|
||||
if (ping.busy) {
|
||||
ResponseCmndChar_P(PSTR("Ping busy"));
|
||||
return;
|
||||
}
|
||||
if (count > 10) { count = 8; } // max 8 seconds
|
||||
|
||||
if (WiFi.hostByName(XdrvMailbox.data, ip)) {
|
||||
memset(&ping_opt, 0, sizeof(ping_opt));
|
||||
memset(&ping, 0, sizeof(ping));
|
||||
ping.min_time = UINT32_MAX;
|
||||
|
||||
ping_opt.count = count;
|
||||
ping_opt.coarse_time = 1; // wait 1 second between messages
|
||||
ping_opt.ip = ip;
|
||||
|
||||
// callbacks
|
||||
ping_opt.recv_function = (ping_recv_function) ping_recv_cb; // at each response or time-out
|
||||
ping_opt.sent_function = (ping_sent_function) ping_sent_cb; // when all packets have been sent and reveived
|
||||
|
||||
ping.busy = true;
|
||||
if (ping_start(&ping_opt)) {
|
||||
bool ok = t_ping_start(ip, count);
|
||||
if (ok) {
|
||||
ResponseCmndDone();
|
||||
} else {
|
||||
ResponseCmndChar_P(PSTR("Unable to send Ping"));
|
||||
ping.busy = false;
|
||||
ResponseCmndChar_P(PSTR("Ping already ongoing for this IP"));
|
||||
}
|
||||
} else {
|
||||
ResponseCmndChar_P(PSTR("Unable to resolve IP address"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -157,7 +332,7 @@ bool Xdrv38(uint8_t function)
|
||||
|
||||
switch (function) {
|
||||
case FUNC_EVERY_250_MSECOND:
|
||||
PingResponsePoll();
|
||||
PingResponsePoll(); // TODO
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kPingCommands, PingCommand);
|
||||
@ -166,4 +341,4 @@ bool Xdrv38(uint8_t function)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_PING
|
||||
#endif // USE_PING
|
@ -172,11 +172,11 @@ void CpuLoadLoop(void)
|
||||
CPU_loops ++;
|
||||
if ((CPU_last_millis + (CPU_load_check *1000)) <= CPU_last_loop_time) {
|
||||
#if defined(F_CPU) && (F_CPU == 160000000L)
|
||||
int CPU_load = 100 - ( (CPU_loops*(1 + 30*sleep)) / (CPU_load_check *800) );
|
||||
int CPU_load = 100 - ( (CPU_loops*(1 + 30*ssleep)) / (CPU_load_check *800) );
|
||||
CPU_loops = CPU_loops / CPU_load_check;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, CPU %d%%(160MHz), Loops/sec %d"), ESP.getFreeHeap(), CPU_load, CPU_loops);
|
||||
#else
|
||||
int CPU_load = 100 - ( (CPU_loops*(1 + 30*sleep)) / (CPU_load_check *400) );
|
||||
int CPU_load = 100 - ( (CPU_loops*(1 + 30*ssleep)) / (CPU_load_check *400) );
|
||||
CPU_loops = CPU_loops / CPU_load_check;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, CPU %d%%(80MHz), Loops/sec %d"), ESP.getFreeHeap(), CPU_load, CPU_loops);
|
||||
#endif
|
||||
@ -188,6 +188,7 @@ void CpuLoadLoop(void)
|
||||
|
||||
/*******************************************************************************************/
|
||||
|
||||
#ifdef ESP8266
|
||||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1)
|
||||
// All version before core 2.4.2
|
||||
// https://github.com/esp8266/Arduino/issues/2557
|
||||
@ -224,10 +225,22 @@ void DebugFreeMem(void)
|
||||
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_x_x
|
||||
|
||||
#else // ESP32
|
||||
|
||||
void DebugFreeMem(void)
|
||||
{
|
||||
register uint8_t *sp asm("a1");
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), ESP.getFreeHeap(), sp - pxTaskGetStackStart(NULL), XdrvMailbox.data);
|
||||
}
|
||||
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
/*******************************************************************************************/
|
||||
|
||||
void DebugRtcDump(char* parms)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
#define CFG_COLS 16
|
||||
|
||||
uint16_t idx;
|
||||
@ -283,6 +296,7 @@ void DebugRtcDump(char* parms)
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("%s|"), log_data);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
}
|
||||
#endif // ESP8266
|
||||
}
|
||||
|
||||
/*******************************************************************************************/
|
||||
@ -298,7 +312,7 @@ void DebugCfgDump(char* parms)
|
||||
char *p;
|
||||
|
||||
uint8_t *buffer = (uint8_t *) &Settings;
|
||||
maxrow = ((sizeof(SYSCFG)+CFG_COLS)/CFG_COLS);
|
||||
maxrow = ((sizeof(Settings)+CFG_COLS)/CFG_COLS);
|
||||
|
||||
uint16_t srow = strtol(parms, &p, 16) / CFG_COLS;
|
||||
uint16_t mrow = strtol(p, &p, 10);
|
||||
@ -342,7 +356,7 @@ void DebugCfgPeek(char* parms)
|
||||
char *p;
|
||||
|
||||
uint16_t address = strtol(parms, &p, 16);
|
||||
if (address > sizeof(SYSCFG)) address = sizeof(SYSCFG) -4;
|
||||
if (address > sizeof(Settings)) address = sizeof(Settings) -4;
|
||||
address = (address >> 2) << 2;
|
||||
|
||||
uint8_t *buffer = (uint8_t *) &Settings;
|
||||
@ -367,7 +381,7 @@ void DebugCfgPoke(char* parms)
|
||||
char *p;
|
||||
|
||||
uint16_t address = strtol(parms, &p, 16);
|
||||
if (address > sizeof(SYSCFG)) address = sizeof(SYSCFG) -4;
|
||||
if (address > sizeof(Settings)) address = sizeof(Settings) -4;
|
||||
address = (address >> 2) << 2;
|
||||
|
||||
uint32_t data = strtol(p, &p, 16);
|
||||
@ -385,6 +399,7 @@ void DebugCfgPoke(char* parms)
|
||||
|
||||
void SetFlashMode(uint8_t mode)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
uint8_t *_buffer;
|
||||
uint32_t address;
|
||||
|
||||
@ -400,6 +415,7 @@ void SetFlashMode(uint8_t mode)
|
||||
}
|
||||
}
|
||||
delete[] _buffer;
|
||||
#endif // ESP8266
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -503,6 +519,7 @@ uint32_t DebugSwap32(uint32_t x) {
|
||||
|
||||
void CmndFlashDump(void)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
// FlashDump
|
||||
// FlashDump 0xFF000
|
||||
// FlashDump 0xFC000 10
|
||||
@ -533,6 +550,7 @@ void CmndFlashDump(void)
|
||||
DebugSwap32(values[4]), DebugSwap32(values[5]), DebugSwap32(values[6]), DebugSwap32(values[7]));
|
||||
}
|
||||
ResponseCmndDone();
|
||||
#endif // ESP8266
|
||||
}
|
||||
|
||||
#ifdef USE_I2C
|
||||
@ -600,10 +618,12 @@ void CmndI2cRead(void)
|
||||
|
||||
void CmndI2cStretch(void)
|
||||
{
|
||||
#ifdef ESP8266
|
||||
if (i2c_flg && (XdrvMailbox.payload > 0)) {
|
||||
Wire.setClockStretchLimit(XdrvMailbox.payload);
|
||||
}
|
||||
ResponseCmndDone();
|
||||
#endif // ESP8266
|
||||
}
|
||||
|
||||
void CmndI2cClock(void)
|
||||
|
@ -59,14 +59,18 @@
|
||||
|
||||
const char kHtuTypes[] PROGMEM = "HTU21|SI7013|SI7020|SI7021|T/RH?";
|
||||
|
||||
uint8_t htu_address;
|
||||
uint8_t htu_type = 0;
|
||||
uint8_t htu_delay_temp;
|
||||
uint8_t htu_delay_humidity = 50;
|
||||
uint8_t htu_valid = 0;
|
||||
float htu_temperature = 0;
|
||||
float htu_humidity = 0;
|
||||
char htu_types[7];
|
||||
struct {
|
||||
float temperature = 0;
|
||||
float humidity = 0;
|
||||
uint8_t address;
|
||||
uint8_t type = 0;
|
||||
uint8_t delay_temp;
|
||||
uint8_t delay_humidity = 50;
|
||||
uint8_t valid = 0;
|
||||
char types[7];
|
||||
} Htu;
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
uint8_t HtuCheckCrc8(uint16_t data)
|
||||
{
|
||||
@ -82,6 +86,8 @@ uint8_t HtuCheckCrc8(uint16_t data)
|
||||
|
||||
uint8_t HtuReadDeviceId(void)
|
||||
{
|
||||
HtuReset(); // Fixes ESP32 sensor loss at restart
|
||||
|
||||
uint16_t deviceID = 0;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
@ -146,12 +152,12 @@ bool HtuRead(void)
|
||||
uint8_t checksum = 0;
|
||||
uint16_t sensorval = 0;
|
||||
|
||||
if (htu_valid) { htu_valid--; }
|
||||
if (Htu.valid) { Htu.valid--; }
|
||||
|
||||
Wire.beginTransmission(HTU21_ADDR);
|
||||
Wire.write(HTU21_READTEMP);
|
||||
if (Wire.endTransmission() != 0) { return false; } // In case of error
|
||||
delay(htu_delay_temp); // Sensor time at max resolution
|
||||
delay(Htu.delay_temp); // Sensor time at max resolution
|
||||
|
||||
Wire.requestFrom(HTU21_ADDR, 3);
|
||||
if (3 == Wire.available()) {
|
||||
@ -161,12 +167,12 @@ bool HtuRead(void)
|
||||
}
|
||||
if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch
|
||||
|
||||
htu_temperature = ConvertTemp(0.002681 * (float)sensorval - 46.85);
|
||||
Htu.temperature = ConvertTemp(0.002681 * (float)sensorval - 46.85);
|
||||
|
||||
Wire.beginTransmission(HTU21_ADDR);
|
||||
Wire.write(HTU21_READHUM);
|
||||
if (Wire.endTransmission() != 0) { return false; } // In case of error
|
||||
delay(htu_delay_humidity); // Sensor time at max resolution
|
||||
delay(Htu.delay_humidity); // Sensor time at max resolution
|
||||
|
||||
Wire.requestFrom(HTU21_ADDR, 3);
|
||||
if (3 <= Wire.available()) {
|
||||
@ -177,19 +183,19 @@ bool HtuRead(void)
|
||||
if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch
|
||||
|
||||
sensorval ^= 0x02; // clear status bits
|
||||
htu_humidity = 0.001907 * (float)sensorval - 6;
|
||||
if (htu_humidity > 100) { htu_humidity = 100.0; }
|
||||
if (htu_humidity < 0) { htu_humidity = 0.01; }
|
||||
Htu.humidity = 0.001907 * (float)sensorval - 6;
|
||||
if (Htu.humidity > 100) { Htu.humidity = 100.0; }
|
||||
if (Htu.humidity < 0) { Htu.humidity = 0.01; }
|
||||
|
||||
if ((0.00 == htu_humidity) && (0.00 == htu_temperature)) {
|
||||
htu_humidity = 0.0;
|
||||
if ((0.00 == Htu.humidity) && (0.00 == Htu.temperature)) {
|
||||
Htu.humidity = 0.0;
|
||||
}
|
||||
if ((htu_temperature > 0.00) && (htu_temperature < 80.00)) {
|
||||
htu_humidity = (-0.15) * (25 - htu_temperature) + htu_humidity;
|
||||
if ((Htu.temperature > 0.00) && (Htu.temperature < 80.00)) {
|
||||
Htu.humidity = (-0.15) * (25 - Htu.temperature) + Htu.humidity;
|
||||
}
|
||||
htu_humidity = ConvertHumidity(htu_humidity);
|
||||
Htu.humidity = ConvertHumidity(Htu.humidity);
|
||||
|
||||
htu_valid = SENSOR_MAX_MISS;
|
||||
Htu.valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -197,17 +203,17 @@ bool HtuRead(void)
|
||||
|
||||
void HtuDetect(void)
|
||||
{
|
||||
htu_address = HTU21_ADDR;
|
||||
if (I2cActive(htu_address)) { return; }
|
||||
Htu.address = HTU21_ADDR;
|
||||
if (I2cActive(Htu.address)) { return; }
|
||||
|
||||
htu_type = HtuReadDeviceId();
|
||||
if (htu_type) {
|
||||
Htu.type = HtuReadDeviceId();
|
||||
if (Htu.type) {
|
||||
uint8_t index = 0;
|
||||
HtuInit();
|
||||
switch (htu_type) {
|
||||
switch (Htu.type) {
|
||||
case HTU21_CHIPID:
|
||||
htu_delay_temp = 50;
|
||||
htu_delay_humidity = 16;
|
||||
Htu.delay_temp = 50;
|
||||
Htu.delay_humidity = 16;
|
||||
break;
|
||||
case SI7021_CHIPID:
|
||||
index++; // 3
|
||||
@ -215,16 +221,16 @@ void HtuDetect(void)
|
||||
index++; // 2
|
||||
case SI7013_CHIPID:
|
||||
index++; // 1
|
||||
htu_delay_temp = 12;
|
||||
htu_delay_humidity = 23;
|
||||
Htu.delay_temp = 12;
|
||||
Htu.delay_humidity = 23;
|
||||
break;
|
||||
default:
|
||||
index = 4;
|
||||
htu_delay_temp = 50;
|
||||
htu_delay_humidity = 23;
|
||||
Htu.delay_temp = 50;
|
||||
Htu.delay_humidity = 23;
|
||||
}
|
||||
GetTextIndexed(htu_types, sizeof(htu_types), index, kHtuTypes);
|
||||
I2cSetActiveFound(htu_address, htu_types);
|
||||
GetTextIndexed(Htu.types, sizeof(Htu.types), index, kHtuTypes);
|
||||
I2cSetActiveFound(Htu.address, Htu.types);
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,15 +239,15 @@ void HtuEverySecond(void)
|
||||
if (uptime &1) { // Every 2 seconds
|
||||
// HTU21: 68mS, SI70xx: 37mS
|
||||
if (!HtuRead()) {
|
||||
AddLogMissed(htu_types, htu_valid);
|
||||
AddLogMissed(Htu.types, Htu.valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HtuShow(bool json)
|
||||
{
|
||||
if (htu_valid) {
|
||||
TempHumDewShow(json, (0 == tele_period), htu_types, htu_temperature, htu_humidity);
|
||||
if (Htu.valid) {
|
||||
TempHumDewShow(json, (0 == tele_period), Htu.types, Htu.temperature, Htu.humidity);
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +264,7 @@ bool Xsns08(uint8_t function)
|
||||
if (FUNC_INIT == function) {
|
||||
HtuDetect();
|
||||
}
|
||||
else if (htu_type) {
|
||||
else if (Htu.type) {
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
HtuEverySecond();
|
||||
|
@ -32,40 +32,39 @@
|
||||
#define XSNS_22 22
|
||||
|
||||
uint8_t sr04_type = 1;
|
||||
int sr04_echo_pin = 0;
|
||||
int sr04_trig_pin = 0;
|
||||
real64_t distance;
|
||||
|
||||
NewPing* sonar = nullptr;
|
||||
TasmotaSerial* sonar_serial = nullptr;
|
||||
|
||||
|
||||
|
||||
uint8_t Sr04TModeDetect(void)
|
||||
{
|
||||
sr04_type = 0;
|
||||
if (pin[GPIO_SR04_ECHO]>=99) return sr04_type;
|
||||
if (99 == pin[GPIO_SR04_ECHO]) { return sr04_type; }
|
||||
|
||||
sr04_echo_pin = pin[GPIO_SR04_ECHO];
|
||||
sr04_trig_pin = (pin[GPIO_SR04_TRIG] < 99) ? pin[GPIO_SR04_TRIG] : -1;
|
||||
int sr04_echo_pin = pin[GPIO_SR04_ECHO];
|
||||
int sr04_trig_pin = (pin[GPIO_SR04_TRIG] < 99) ? pin[GPIO_SR04_TRIG] : pin[GPIO_SR04_ECHO]; // if GPIO_SR04_TRIG is not configured use single PIN mode with GPIO_SR04_ECHO only
|
||||
sonar_serial = new TasmotaSerial(sr04_echo_pin, sr04_trig_pin, 1);
|
||||
|
||||
if (sonar_serial->begin(9600,1)) {
|
||||
DEBUG_SENSOR_LOG(PSTR("SR04: Detect mode"));
|
||||
|
||||
if (sr04_trig_pin!=-1) {
|
||||
sr04_type = (Sr04TMiddleValue(Sr04TMode3Distance(),Sr04TMode3Distance(),Sr04TMode3Distance())!=NO_ECHO)?3:1;
|
||||
if (sr04_trig_pin != -1) {
|
||||
sr04_type = (Sr04TMiddleValue(Sr04TMode3Distance(), Sr04TMode3Distance(), Sr04TMode3Distance()) != NO_ECHO) ? 3 : 1;
|
||||
} else {
|
||||
sr04_type = 2;
|
||||
sr04_type = 2;
|
||||
}
|
||||
} else {
|
||||
sr04_type = 1;
|
||||
}
|
||||
|
||||
if (sr04_type < 2) {
|
||||
delete sonar_serial;
|
||||
sonar_serial = nullptr;
|
||||
sonar = new NewPing(sr04_trig_pin, sr04_echo_pin, 300);
|
||||
delete sonar_serial;
|
||||
sonar_serial = nullptr;
|
||||
if (-1 == sr04_trig_pin) {
|
||||
sr04_trig_pin = pin[GPIO_SR04_ECHO]; // if GPIO_SR04_TRIG is not configured use single PIN mode with GPIO_SR04_ECHO only
|
||||
}
|
||||
sonar = new NewPing(sr04_trig_pin, sr04_echo_pin, 300);
|
||||
} else {
|
||||
if (sonar_serial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
|
@ -494,7 +494,7 @@ void HandleHxAction(void)
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_HX711);
|
||||
|
||||
if (WebServer->hasArg("save")) {
|
||||
if (Webserver->hasArg("save")) {
|
||||
HxSaveSettings();
|
||||
HandleConfiguration();
|
||||
return;
|
||||
@ -502,7 +502,7 @@ void HandleHxAction(void)
|
||||
|
||||
char stemp1[20];
|
||||
|
||||
if (WebServer->hasArg("reset")) {
|
||||
if (Webserver->hasArg("reset")) {
|
||||
snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 1")); // Reset
|
||||
ExecuteWebCommand(stemp1, SRC_WEBGUI);
|
||||
|
||||
@ -510,7 +510,7 @@ void HandleHxAction(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (WebServer->hasArg("calibrate")) {
|
||||
if (Webserver->hasArg("calibrate")) {
|
||||
WebGetArg("p1", stemp1, sizeof(stemp1));
|
||||
Settings.weight_reference = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToFloat(stemp1) * 1000);
|
||||
|
||||
@ -593,7 +593,7 @@ bool Xsns34(uint8_t function)
|
||||
WSContentSend_P(HTTP_BTN_MENU_HX711);
|
||||
break;
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/" WEB_HANDLE_HX711, HandleHxAction);
|
||||
Webserver->on("/" WEB_HANDLE_HX711, HandleHxAction);
|
||||
break;
|
||||
#endif // USE_HX711_GUI
|
||||
#endif // USE_WEBSERVER
|
||||
|
@ -98,7 +98,7 @@ The serial pins are GPS_RX and GPS_TX, no further installation steps needed. To
|
||||
set latitude and longitude in settings
|
||||
|
||||
+ sensor60 14
|
||||
open virtual serial port over TCP, usable for u-center
|
||||
open virtual serial port over TCP, usable for u-center
|
||||
|
||||
+ sensor60 15
|
||||
pause virtual serial port over TCP
|
||||
@ -119,10 +119,6 @@ rule3 on tele-FLOG#sec do DisplayText [f0c1l4]SAV:%value% endon on tele-FLOG#r
|
||||
#include "NTPServer.h"
|
||||
#include "NTPPacket.h"
|
||||
|
||||
#ifdef ESP32
|
||||
#include <HardwareSerial.h>
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************\
|
||||
* constants
|
||||
\*********************************************************************************************/
|
||||
@ -137,7 +133,7 @@ const char kUBXTypes[] PROGMEM = "UBX";
|
||||
|
||||
#define UBX_SERIAL_BUFFER_SIZE 256
|
||||
#define UBX_TCP_PORT 1234
|
||||
#define NTP_MILLIS_OFFSET 50 // estimated latency in milliseconds
|
||||
#define NTP_MILLIS_OFFSET 50 // estimated latency in milliseconds
|
||||
|
||||
/********************************************************************************************\
|
||||
| *globals
|
||||
@ -299,11 +295,7 @@ enum UBXMsgType {
|
||||
#ifdef USE_FLOG
|
||||
FLOG *Flog = nullptr;
|
||||
#endif //USE_FLOG
|
||||
#ifdef ESP8266
|
||||
TasmotaSerial *UBXSerial;
|
||||
#else
|
||||
HardwareSerial *UBXSerial;
|
||||
#endif
|
||||
|
||||
NtpServer timeServer(PortUdp);
|
||||
|
||||
@ -363,21 +355,13 @@ void UBXDetect(void)
|
||||
{
|
||||
UBX.mode.init = 0;
|
||||
if ((pin[GPIO_GPS_RX] < 99) && (pin[GPIO_GPS_TX] < 99)) {
|
||||
#ifdef ESP8266
|
||||
UBXSerial = new TasmotaSerial(pin[GPIO_GPS_RX], pin[GPIO_GPS_TX], 1, 0, UBX_SERIAL_BUFFER_SIZE); // 64 byte buffer is NOT enough
|
||||
if (UBXSerial->begin(9600)) {
|
||||
#else
|
||||
UBXSerial = new HardwareSerial(2);
|
||||
UBXSerial->begin(9600,SERIAL_8N1,pin[GPIO_GPS_RX], pin[GPIO_GPS_TX]);
|
||||
{
|
||||
#endif
|
||||
DEBUG_SENSOR_LOG(PSTR("UBX: started serial"));
|
||||
#ifdef ESP8266
|
||||
if (UBXSerial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
DEBUG_SENSOR_LOG(PSTR("UBX: claim HW"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -504,8 +488,8 @@ uint32_t UBXprocessGPS()
|
||||
#ifdef USE_FLOG
|
||||
void UBXsendHeader(void)
|
||||
{
|
||||
WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||
WebServer->sendHeader(F("Content-Disposition"), F("attachment; filename=TASMOTA.gpx"));
|
||||
Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||
Webserver->sendHeader(F("Content-Disposition"), F("attachment; filename=TASMOTA.gpx"));
|
||||
WSSend(200, CT_STREAM, F(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\r\n"
|
||||
"<GPX version=\"1.1\" creator=\"TASMOTA\" xmlns=\"http://www.topografix.com/GPX/1/1\" \r\n"
|
||||
@ -526,13 +510,13 @@ void UBXsendRecord(uint8_t *buf)
|
||||
dtostrfd((double)entry->lon/10000000.0f,7,lon);
|
||||
snprintf_P(record, sizeof(record),PSTR("<trkpt\n\t lat=\"%s\" lon=\"%s\">\n\t<time>%s</time>\n</trkpt>\n"),lat ,lon, stime);
|
||||
// DEBUG_SENSOR_LOG(PSTR("FLOG: DL %u %u"), Flog->sector.dword_buffer[k+j],Flog->sector.dword_buffer[k+j+1]);
|
||||
WebServer->sendContent_P(record);
|
||||
Webserver->sendContent_P(record);
|
||||
}
|
||||
|
||||
void UBXsendFooter(void)
|
||||
{
|
||||
WebServer->sendContent(F("</trkseg>\n</trk>\n</gpx>"));
|
||||
WebServer->sendContent("");
|
||||
Webserver->sendContent(F("</trkseg>\n</trk>\n</gpx>"));
|
||||
Webserver->sendContent("");
|
||||
Rtc.user_time_entry = false; // we have blocked the main loop and want a new valid time
|
||||
}
|
||||
|
||||
@ -707,7 +691,7 @@ void UBXHandleTIME()
|
||||
if (UBX.mode.forceUTCupdate || Rtc.user_time_entry == false){
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("UBX: UTC-Time is valid, set system time"));
|
||||
Rtc.utc_time = UBX.rec_buffer.values.time;
|
||||
}
|
||||
}
|
||||
Rtc.user_time_entry = true;
|
||||
}
|
||||
}
|
||||
@ -928,7 +912,7 @@ bool Xsns60(uint8_t function)
|
||||
break;
|
||||
#ifdef USE_FLOG
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/UBX", UBXsendFile);
|
||||
Webserver->on("/UBX", UBXsendFile);
|
||||
break;
|
||||
#endif //USE_FLOG
|
||||
case FUNC_JSON_APPEND:
|
||||
|
@ -90,7 +90,7 @@ bool Xsns91(uint8_t function)
|
||||
|
||||
switch (function) {
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
WebServer->on("/metrics", HandleMetrics);
|
||||
Webserver->on("/metrics", HandleMetrics);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
Loading…
x
Reference in New Issue
Block a user