Merge branch 'development' into neopool-dev

This commit is contained in:
Norbert Richter 2021-01-31 20:56:59 +01:00
commit 5e14eac558
No known key found for this signature in database
GPG Key ID: 6628701A626FA674
37 changed files with 504 additions and 342 deletions

View File

@ -6,7 +6,15 @@ All notable changes to this project will be documented in this file.
## [9.2.0.4] ## [9.2.0.4]
### Added ### Added
- Function ``AddLog`` to provide logging for up to 128 (LOGSZ) characters to save stack space - Function ``AddLog`` to provide logging for up to 128 (LOGSZ) characters to save stack space
- Commands ``ChannelRemap``, ``MultiPWM``, ``AlexaCTRange``, ``PowerOnFade``, ``PWMCT``, ``WhiteBlend``, ``VirtualCT`` as synonyms for ``SetOption37, 68, 82, 91, 92, 105 and 106`` respectively - Commands ``ChannelRemap``, ``MultiPWM``, ``AlexaCTRange``, ``PowerOnFade``, ``PWMCT``, ``WhiteBlend`` and ``VirtualCT`` as synonyms for ``SetOption37, 68, 82, 91, 92, 105`` and ``106``
- Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind`` and ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110`` and ``112``
- Commands ``ZbNoAutoBind``, ``ZbReceivedTopic`` and ``ZbOmitDevice`` as synonyms for ``SetOption116, 118`` and ``119``
- Commands ``BuzzerActive`` and ``BuzzerPwm`` as synonyms for ``SetOption67`` and ``111``
- Support for ESP32 ``Module 5`` Wireless Tag Eth01 (#9496)
- Support trailing silence in buzzer tune (#10694)
- Command ``L1MusicSync <0|Off>|<1|On>|<2|Toggle>, 1..10, 1..100>`` to control Sonoff L1 Music Sync mode sensitivity and speed (#10722)
- Command ``Speed2`` to control a once off fade (#10741)
- Zigbee command ``SetOption120 1`` or ``ZbEndpointTopic 1`` to add the endpoint as suffix in topic when using ``SetOption89 1``
### Changed ### Changed
- Maximum chars in ``AddLog_P`` logging restored from 128 to 700 (MAX_LOGSZ) to solve broken error messages - Maximum chars in ``AddLog_P`` logging restored from 128 to 700 (MAX_LOGSZ) to solve broken error messages
@ -24,7 +32,7 @@ All notable changes to this project will be documented in this file.
- Compile time option ``USE_MQTT_TLS_DROP_OLD_FINGERPRINT`` to drop old (less secure) TLS fingerprint - Compile time option ``USE_MQTT_TLS_DROP_OLD_FINGERPRINT`` to drop old (less secure) TLS fingerprint
- Command ``SetOption40 0..250`` to disable button functionality if activated for over 0.1 second re-introduced - Command ``SetOption40 0..250`` to disable button functionality if activated for over 0.1 second re-introduced
- Support for SM2135 current selection using GPIO ``SM2135 DAT`` index (#10634) - Support for SM2135 current selection using GPIO ``SM2135 DAT`` index (#10634)
- Basic support for ESP32 M5stack core2 16MB binary tasmota32-core2.bin (#10635) - Support for ESP32 ``Module 7`` M5stack core2 16MB binary tasmota32-core2.bin (#10635)
- Support for Sugar Valley NeoPool Controller by Norbert Richter (#10637) - Support for Sugar Valley NeoPool Controller by Norbert Richter (#10637)
- Rule trigger string comparisons for EndsWith ``$>``, StartsWith ``$<`` and Contains ``$|`` (#10538) - Rule trigger string comparisons for EndsWith ``$>``, StartsWith ``$<`` and Contains ``$|`` (#10538)
- Support for TOF10120 time of flight sensor by Cyril Pawelko (#10190) - Support for TOF10120 time of flight sensor by Cyril Pawelko (#10190)
@ -41,7 +49,7 @@ All notable changes to this project will be documented in this file.
## [9.2.0.2] 20210105 ## [9.2.0.2] 20210105
### Added ### Added
- Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) - Support for ESP32 ``Module 3`` Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630)
- Command ``CTRange`` to specify the visible CT range the bulb is capable of (#10311) - Command ``CTRange`` to specify the visible CT range the bulb is capable of (#10311)
- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels (#10311) - Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels (#10311)
- Command ``SetOption118 1`` to move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default (#10353) - Command ``SetOption118 1`` to move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default (#10353)

View File

@ -59,13 +59,19 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
## Changelog v9.2.0.4 ## Changelog v9.2.0.4
### Added ### Added
- Command ``CTRange`` to specify the visible CT range the bulb is capable of [#10311](https://github.com/arendst/Tasmota/issues/10311) - Command ``CTRange`` to specify the visible CT range the bulb is capable of [#10311](https://github.com/arendst/Tasmota/issues/10311)
- Command ``L1MusicSync <0|Off>|<1|On>|<2|Toggle>, 1..10, 1..100>`` to control Sonoff L1 Music Sync mode sensitivity and speed [#10722](https://github.com/arendst/Tasmota/issues/10722)
- Command ``RuleTimer0`` to access all RuleTimers at once [#10352](https://github.com/arendst/Tasmota/issues/10352) - Command ``RuleTimer0`` to access all RuleTimers at once [#10352](https://github.com/arendst/Tasmota/issues/10352)
- Command ``Speed2`` to control a once off fade [#10741](https://github.com/arendst/Tasmota/issues/10741)
- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels [#10311](https://github.com/arendst/Tasmota/issues/10311) - Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels [#10311](https://github.com/arendst/Tasmota/issues/10311)
- Command ``SetOption40 0..250`` to disable button functionality if activated for over 0.1 second re-introduced - Command ``SetOption40 0..250`` to disable button functionality if activated for over 0.1 second re-introduced
- Command ``SetOption43 1..255`` to control Rotary step (#10407) - Command ``SetOption43 1..255`` to control Rotary step (#10407)
- Command ``SetOption118 1`` to move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default [#10353](https://github.com/arendst/Tasmota/issues/10353) - Command ``SetOption118 1`` to move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default [#10353](https://github.com/arendst/Tasmota/issues/10353)
- Command ``SetOption119 1`` to remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic [#10355](https://github.com/arendst/Tasmota/issues/10355) - Command ``SetOption119 1`` to remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic [#10355](https://github.com/arendst/Tasmota/issues/10355)
- Commands ``ChannelRemap``, ``MultiPWM``, ``AlexaCTRange``, ``PowerOnFade``, ``PWMCT``, ``WhiteBlend``, ``VirtualCT`` as synonyms for ``SetOption37, 68, 82, 91, 92, 105 and 106`` respectively - Zigbee command ``SetOption120 1`` or ``ZbEndpointTopic 1`` to add the zigbee endpoint as suffix in topic when using ``SetOption89 1``
- Commands ``ChannelRemap``, ``MultiPWM``, ``AlexaCTRange``, ``PowerOnFade``, ``PWMCT``, ``WhiteBlend`` and ``VirtualCT`` as synonyms for ``SetOption37, 68, 82, 91, 92, 105`` and ``106``
- Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind`` and ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110`` and ``112``
- Commands ``ZbNoAutoBind``, ``ZbReceivedTopic`` and ``ZbOmitDevice`` as synonyms for ``SetOption116, 118`` and ``119``
- Commands ``BuzzerActive`` and ``BuzzerPwm`` as synonyms for ``SetOption67`` and ``111``
- Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152) - Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152)
- Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196)
- Rotary No Pullup GPIO selection ``Rotary A/B_n`` [#10407](https://github.com/arendst/Tasmota/issues/10407) - Rotary No Pullup GPIO selection ``Rotary A/B_n`` [#10407](https://github.com/arendst/Tasmota/issues/10407)
@ -84,10 +90,12 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
- Support for 24/26/32/34 bit RFID Wiegand interface (D0/D1) by Sigurd Leuther [#3647](https://github.com/arendst/Tasmota/issues/3647) - Support for 24/26/32/34 bit RFID Wiegand interface (D0/D1) by Sigurd Leuther [#3647](https://github.com/arendst/Tasmota/issues/3647)
- Support for SM2135 current selection using GPIO ``SM2135 DAT`` index [#10634](https://github.com/arendst/Tasmota/issues/10634) - Support for SM2135 current selection using GPIO ``SM2135 DAT`` index [#10634](https://github.com/arendst/Tasmota/issues/10634)
- Support for Sugar Valley NeoPool Controller by Norbert Richter [#10637](https://github.com/arendst/Tasmota/issues/10637) - Support for Sugar Valley NeoPool Controller by Norbert Richter [#10637](https://github.com/arendst/Tasmota/issues/10637)
- Support for ESP32 ``Module 3`` Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630)
- Support for ESP32 ``Module 5`` Wireless Tag Eth01 [#9496](https://github.com/arendst/Tasmota/issues/9496)
- Support for ESP32 ``Module 7`` M5stack core2 16MB binary tasmota32-core2.bin [#10635](https://github.com/arendst/Tasmota/issues/10635)
- Support rotary encoder on Shelly Dimmer [#10407](https://github.com/arendst/Tasmota/issues/10407#issuecomment-756240920) - Support rotary encoder on Shelly Dimmer [#10407](https://github.com/arendst/Tasmota/issues/10407#issuecomment-756240920)
- Support character `#` to be replaced by `space`-character in command ``Publish`` topic [#10258](https://github.com/arendst/Tasmota/issues/10258) - Support character `#` to be replaced by `space`-character in command ``Publish`` topic [#10258](https://github.com/arendst/Tasmota/issues/10258)
- Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630) - Support trailing silence in buzzer tune [#10694](https://github.com/arendst/Tasmota/issues/10694)
- Basic support for ESP32 M5stack core2 16MB binary tasmota32-core2.bin [#10635](https://github.com/arendst/Tasmota/issues/10635)
- Rule trigger string comparisons for EndsWith ``$>``, StartsWith ``$<`` and Contains ``$|`` [#10538](https://github.com/arendst/Tasmota/issues/10538) - Rule trigger string comparisons for EndsWith ``$>``, StartsWith ``$<`` and Contains ``$|`` [#10538](https://github.com/arendst/Tasmota/issues/10538)
- SPI display driver SSD1331 Color oled by Jeroen Vermeulen [#10376](https://github.com/arendst/Tasmota/issues/10376) - SPI display driver SSD1331 Color oled by Jeroen Vermeulen [#10376](https://github.com/arendst/Tasmota/issues/10376)
- Compile time option ``USE_MQTT_TLS_DROP_OLD_FINGERPRINT`` to drop old (less secure) TLS fingerprint - Compile time option ``USE_MQTT_TLS_DROP_OLD_FINGERPRINT`` to drop old (less secure) TLS fingerprint

View File

@ -349,7 +349,11 @@
#define D_CMND_CPU_FREQUENCY "CpuFrequency" #define D_CMND_CPU_FREQUENCY "CpuFrequency"
#endif // ESP32 #endif // ESP32
// Commands xdrv_01_mqtt.ino // Commands xdrv_02_mqtt.ino
#define D_SO_MQTTJSONONLY "MqttJSONOnly"
#define D_SO_MQTTTLS "MqttTLS"
#define D_SO_MQTTNORETAIN "MqttNoRetain"
#define D_SO_MQTTDETACHRELAY "MqttDetachRelay"
#define D_CMND_MQTTLOG "MqttLog" #define D_CMND_MQTTLOG "MqttLog"
#define D_CMND_MQTTHOST "MqttHost" #define D_CMND_MQTTHOST "MqttHost"
#define D_CMND_MQTTPORT "MqttPort" #define D_CMND_MQTTPORT "MqttPort"
@ -375,7 +379,7 @@
#define D_CMND_SENSORRETAIN "SensorRetain" #define D_CMND_SENSORRETAIN "SensorRetain"
#define D_CMND_PUBLISH "Publish" #define D_CMND_PUBLISH "Publish"
// Commands xdrv_02_webserver.ino // Commands xdrv_01_webserver.ino
#define D_CMND_WEBSERVER "Webserver" #define D_CMND_WEBSERVER "Webserver"
#define D_JSON_WEBSERVER_MODE "WebServerMode" #define D_JSON_WEBSERVER_MODE "WebServerMode"
#define D_JSON_ACTIVE_FOR "Active for" #define D_JSON_ACTIVE_FOR "Active for"
@ -535,6 +539,10 @@
#define D_SO_ZIGBEE_ENDPOINTSUFFIX "EndpointSuffix" #define D_SO_ZIGBEE_ENDPOINTSUFFIX "EndpointSuffix"
#define D_SO_ZIGBEE_NOAUTOBIND "NoAutoBind" #define D_SO_ZIGBEE_NOAUTOBIND "NoAutoBind"
#define D_SO_ZIGBEE_NAMETOPIC "NameTopic" #define D_SO_ZIGBEE_NAMETOPIC "NameTopic"
#define D_SO_ZIGBEE_ENDPOINTTOPIC "EndpointTopic"
#define D_SO_ZIGBEE_NOAUTOBIND "NoAutoBind"
#define D_SO_ZIGBEE_ZBRECEIVEDTOPIC "ReceivedTopic"
#define D_SO_ZIGBEE_OMITDEVICE "OmitDevice"
#define D_ZIGBEE_NOT_STARTED "Zigbee not started" #define D_ZIGBEE_NOT_STARTED "Zigbee not started"
#define D_CMND_ZIGBEE_PERMITJOIN "PermitJoin" #define D_CMND_ZIGBEE_PERMITJOIN "PermitJoin"
#define D_CMND_ZIGBEE_STATUS "Status" #define D_CMND_ZIGBEE_STATUS "Status"
@ -742,7 +750,6 @@ const char S_JSON_COMMAND_INDEX_NVALUE[] PROGMEM = "{\"%s%d\":%d}";
const char S_JSON_COMMAND_INDEX_LVALUE[] PROGMEM = "{\"%s%d\":%lu}"; const char S_JSON_COMMAND_INDEX_LVALUE[] PROGMEM = "{\"%s%d\":%lu}";
const char S_JSON_COMMAND_INDEX_SVALUE[] PROGMEM = "{\"%s%d\":\"%s\"}"; const char S_JSON_COMMAND_INDEX_SVALUE[] PROGMEM = "{\"%s%d\":\"%s\"}";
const char S_JSON_COMMAND_INDEX_ASTERISK[] PROGMEM = "{\"%s%d\":\"" D_ASTERISK_PWD "\"}"; const char S_JSON_COMMAND_INDEX_ASTERISK[] PROGMEM = "{\"%s%d\":\"" D_ASTERISK_PWD "\"}";
const char S_JSON_COMMAND_INDEX_SVALUE_SVALUE[] PROGMEM = "{\"%s%d\":\"%s%s\"}";
const char S_JSON_SENSOR_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":%d}"; const char S_JSON_SENSOR_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":%d}";
const char S_JSON_SENSOR_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":\"%s\"}"; const char S_JSON_SENSOR_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":\"%s\"}";

View File

@ -849,6 +849,10 @@
#ifdef ESP32 #ifdef ESP32
//#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE) //#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE)
// #define USE_WT32_ETH01 // Add support for Wireless-Tag WT32-ETH01
// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101
// #define ETH_ADDR 1 // [EthAddress] 0 = PHY0 .. 31 = PHY31
// #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT
// Olimex ESP32-PoE // Olimex ESP32-PoE
#define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101
#define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31
@ -856,10 +860,6 @@
// wESP32-PoE // wESP32-PoE
// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 // #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101
// #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 // #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31
// #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT
// Wireless-Tag WT32-ETH01
// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101
// #define ETH_ADDR 1 // [EthAddress] 0 = PHY0 .. 31 = PHY31
// #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT // #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT
#define USE_ADC // Add support for ADC on GPIO32 to GPIO39 #define USE_ADC // Add support for ADC on GPIO32 to GPIO39

View File

@ -145,7 +145,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t fade_fixed_duration : 1; // bit 3 (v9.1.0.2) - SetOption117 - (Light) run fading at fixed duration instead of fixed slew rate uint32_t fade_fixed_duration : 1; // bit 3 (v9.1.0.2) - SetOption117 - (Light) run fading at fixed duration instead of fixed slew rate
uint32_t zb_received_as_subtopic : 1; // bit 4 (v9.2.0.3) - SetOption118 - (Zigbee) Move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default uint32_t zb_received_as_subtopic : 1; // bit 4 (v9.2.0.3) - SetOption118 - (Zigbee) Move ZbReceived from JSON message and into the subtopic replacing "SENSOR" default
uint32_t zb_omit_json_addr : 1; // bit 5 (v9.2.0.3) - SetOption119 - (Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic uint32_t zb_omit_json_addr : 1; // bit 5 (v9.2.0.3) - SetOption119 - (Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic
uint32_t spare06 : 1; // bit 6 uint32_t zb_topic_endpoint : 1; // bit 6 (v9.2.0.4) - SetOption120 - (Zigbee) Append endpoint number to topic if device dependent (use with SetOption89)
uint32_t spare07 : 1; // bit 7 uint32_t spare07 : 1; // bit 7
uint32_t spare08 : 1; // bit 8 uint32_t spare08 : 1; // bit 8
uint32_t spare09 : 1; // bit 9 uint32_t spare09 : 1; // bit 9

View File

@ -1219,29 +1219,15 @@ int ResponseAppendTime(void)
return ResponseAppendTimeFormat(Settings.flag2.time_format); return ResponseAppendTimeFormat(Settings.flag2.time_format);
} }
// int ResponseAppendTHD(float f_temperature, float f_humidity)
// {
// char temperature[FLOATSZ];
// dtostrfd(f_temperature, Settings.flag2.temperature_resolution, temperature);
// char humidity[FLOATSZ];
// dtostrfd(f_humidity, Settings.flag2.humidity_resolution, humidity);
// char dewpoint[FLOATSZ];
// dtostrfd(CalcTempHumToDew(f_temperature, f_humidity), Settings.flag2.temperature_resolution, dewpoint);
// return ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s,\"" D_JSON_DEWPOINT "\":%s"), temperature, humidity, dewpoint);
// }
int ResponseAppendTHD(float f_temperature, float f_humidity) int ResponseAppendTHD(float f_temperature, float f_humidity)
{ {
float dewpoint = CalcTempHumToDew(f_temperature, f_humidity); float dewpoint = CalcTempHumToDew(f_temperature, f_humidity);
return ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%*_f,\"" D_JSON_HUMIDITY "\":%*_f,\"" D_JSON_DEWPOINT "\":%*_f"), return ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%*_f,\"" D_JSON_HUMIDITY "\":%*_f,\"" D_JSON_DEWPOINT "\":%*_f"),
Settings.flag2.temperature_resolution, &f_temperature, Settings.flag2.temperature_resolution, &f_temperature,
Settings.flag2.humidity_resolution, &f_humidity, Settings.flag2.humidity_resolution, &f_humidity,
Settings.flag2.temperature_resolution, &dewpoint); Settings.flag2.temperature_resolution, &dewpoint);
} }
int ResponseJsonEnd(void) int ResponseJsonEnd(void)
{ {
return ResponseAppend_P(PSTR("}")); return ResponseAppend_P(PSTR("}"));

View File

@ -505,21 +505,12 @@ void CmndStatus(void)
} }
if ((0 == payload) || (5 == payload)) { if ((0 == payload) || (5 == payload)) {
/* Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\""
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_GATEWAY "\":\"%s\",\""
D_JSON_SUBNETMASK "\":\"%s\",\"" D_JSON_DNSSERVER "\":\"%s\",\"" D_JSON_MAC "\":\"%s\",\""
D_CMND_WEBSERVER "\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"),
NetworkHostname(), NetworkAddress().toString().c_str(), IPAddress(Settings.ipv4_address[1]).toString().c_str(),
IPAddress(Settings.ipv4_address[2]).toString().c_str(), IPAddress(Settings.ipv4_address[3]).toString().c_str(), NetworkMacAddress().c_str(),
Settings.webserver, Settings.sta_config, WifiGetOutputPower().c_str());
*/
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\""
D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "\":\"%_I\",\""
D_JSON_MAC "\":\"%s\",\"" D_CMND_WEBSERVER "\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"), D_JSON_MAC "\":\"%s\",\"" D_CMND_WEBSERVER "\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"),
NetworkHostname(), NetworkAddress().toString().c_str(), NetworkHostname(), (uint32_t)NetworkAddress(),
Settings.ipv4_address[1], Settings.ipv4_address[2], Settings.ipv4_address[3], Settings.ipv4_address[1], Settings.ipv4_address[2], Settings.ipv4_address[3],
NetworkMacAddress().c_str(), Settings.webserver, Settings.sta_config, WifiGetOutputPower().c_str()); NetworkMacAddress().c_str(), Settings.webserver, Settings.sta_config, WifiGetOutputPower().c_str());
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS "5")); MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS "5"));
} }
@ -1517,23 +1508,20 @@ void CmndLogport(void)
void CmndIpAddress(void) void CmndIpAddress(void)
{ {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) {
char network_address[22];
ext_snprintf_P(network_address, sizeof(network_address), PSTR(" = %_I"), (uint32_t)NetworkAddress());
if (!XdrvMailbox.usridx) { if (!XdrvMailbox.usridx) {
char stemp1[TOPSZ];
snprintf_P(stemp1, sizeof(stemp1), PSTR(" %s"), NetworkAddress().toString().c_str());
ResponseClear(); ResponseClear();
for (uint32_t i = 0; i < 4; i++) { for (uint32_t i = 0; i < 4; i++) {
ResponseAppend_P(PSTR("%c\"%s%d\":\"%s%s\""), (i) ? ',' : '{', XdrvMailbox.command, i +1, IPAddress(Settings.ipv4_address[i]).toString().c_str(), (0 == i) ? stemp1:""); ResponseAppend_P(PSTR("%c\"%s%d\":\"%_I%s\""), (i)?',':'{', XdrvMailbox.command, i +1, Settings.ipv4_address[i], (0 == i)?network_address:"");
} }
ResponseJsonEnd(); ResponseJsonEnd();
} else { } else {
uint32_t ipv4_address; uint32_t ipv4_address;
if (ParseIPv4(&ipv4_address, XdrvMailbox.data)) { if (ParseIPv4(&ipv4_address, XdrvMailbox.data)) {
Settings.ipv4_address[XdrvMailbox.index -1] = ipv4_address; Settings.ipv4_address[XdrvMailbox.index -1] = ipv4_address;
// TasmotaGlobal.restart_flag = 2;
} }
char stemp1[TOPSZ]; Response_P(PSTR("{\"%s%d\":\"%_I%s\"}"), XdrvMailbox.command, XdrvMailbox.index, Settings.ipv4_address[XdrvMailbox.index -1], (1 == XdrvMailbox.index)?network_address:"");
snprintf_P(stemp1, sizeof(stemp1), PSTR(" %s"), NetworkAddress().toString().c_str());
Response_P(S_JSON_COMMAND_INDEX_SVALUE_SVALUE, XdrvMailbox.command, XdrvMailbox.index, IPAddress(Settings.ipv4_address[XdrvMailbox.index -1]).toString().c_str(), (1 == XdrvMailbox.index) ? stemp1:"");
} }
} }
} }

View File

@ -151,8 +151,8 @@ void PollUdp(void)
udp_remote_port = PortUdp.remotePort(); udp_remote_port = PortUdp.remotePort();
#endif #endif
// AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %s:%d\n%s"), // AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %_I:%d\n%s"),
// udp_remote_ip.toString().c_str(), udp_remote_port, packet_buffer); // (uint32_t)udp_remote_ip, udp_remote_port, packet_buffer);
LowerCase(packet_buffer, packet_buffer); LowerCase(packet_buffer, packet_buffer);
RemoveSpace(packet_buffer); RemoveSpace(packet_buffer);

View File

@ -748,7 +748,7 @@ uint32_t WifiGetNtp(void) {
return 0; return 0;
} }
// AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Name %s, IP %s"), ntp_server, time_server_ip.toString().c_str()); // AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Name %s, IP %_I"), ntp_server, (uint32_t)time_server_ip);
WiFiUDP udp; WiFiUDP udp;
@ -798,7 +798,7 @@ uint32_t WifiGetNtp(void) {
if ((packet_buffer[0] & 0b11000000) == 0b11000000) { if ((packet_buffer[0] & 0b11000000) == 0b11000000) {
// Leap-Indicator: unknown (clock unsynchronized) // Leap-Indicator: unknown (clock unsynchronized)
// See: https://github.com/letscontrolit/ESPEasy/issues/2886#issuecomment-586656384 // See: https://github.com/letscontrolit/ESPEasy/issues/2886#issuecomment-586656384
AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: IP %s unsynched"), time_server_ip.toString().c_str()); AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: IP %_I unsynched"), (uint32_t)time_server_ip);
ntp_server_id++; // Next server next time ntp_server_id++; // Next server next time
return 0; return 0;
} }

View File

@ -170,7 +170,10 @@
#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM)
#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #ifdef ESP32
#define USE_BLE_ESP32 // (ESP32 only) Add support for native BLE on ESP32 - use new driver
#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#endif
#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
//#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code)
@ -233,6 +236,7 @@
#undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common) #undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common)
#undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code) #undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code)
#undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code) #undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code)
#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer #undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer
@ -292,6 +296,7 @@
#undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry
#undef USE_IEM3000 // Disable support for Schneider Electric iEM3000-Modbus series energy monitor (+0k8 code) #undef USE_IEM3000 // Disable support for Schneider Electric iEM3000-Modbus series energy monitor (+0k8 code)
#undef USE_WE517 // Disable support for Orno WE517-Modbus energy monitor (+1k code) #undef USE_WE517 // Disable support for Orno WE517-Modbus energy monitor (+1k code)
#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
@ -416,6 +421,7 @@
#undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
#undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM)
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
@ -544,6 +550,7 @@
#undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
#undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM)
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
@ -681,6 +688,7 @@
#undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
#undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM)
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
@ -820,6 +828,7 @@
#undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
#undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM)
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)

View File

@ -472,6 +472,43 @@ bool first_device_group_is_local = true;
#define DEBUG_TRACE_LOG(...) #define DEBUG_TRACE_LOG(...)
#endif #endif
/*********************************************************************************************\
* Macro for SetOption synonyms
*
* SetOption synonyms come first in the list of commands, right after the prefix.
* They don't need any matching function pointer, since they are handled internally.
* So don't forget to NOT put pointers in the functions pointers list.
*
* The additionnal list of unsigned bytes contains the Option numbers of each synonyms
* in the same order. The first byte of the list contains the number of synonyms
* (not including the number itself). The is the number of names to skip to find the first command.
*
* As it si cumbersome to calculate the first byte (number of synonyms), we provide the following
* macro `SO_SYNONYMS(<name>, <list of bytes>)`
*
* For example:
* ```
* SO_SYNONYMS(kLightSynonyms,
* 37, 68, 82, 91, 92, 105,
* 106,
* );
* ```
*
* is equivalent to:
* ```
* const static uint8_t kLightSynonyms[] PROGMEM = {
* 7, // number of synonyms, automatically calculated
* 37, 68, 82, 91, 92, 105,
* 106,
* };
* ```
*
* This comes very handy if you need to adjust the number of synonyms depending on #defines
\*********************************************************************************************/
#define SO_SYNONYMS(N,...) const static uint8_t __syn_array_len_ ## N[] = { __VA_ARGS__ }; /* this first array will not be kept by linker, just used for sizeof() */ const static uint8_t N[] PROGMEM = { sizeof(__syn_array_len_ ## N), __VA_ARGS__ };
/*********************************************************************************************/ /*********************************************************************************************/
#endif // _TASMOTA_GLOBALS_H_ #endif // _TASMOTA_GLOBALS_H_

View File

@ -2350,22 +2350,6 @@ enum SupportedModules {
M5STACK_CORE2, M5STACK_CORE2,
MAXMODULE }; MAXMODULE };
const char kModuleNames[] PROGMEM =
"ESP32-DevKit|"
#ifdef USE_WEBCAM
"ESP32-Cam|"
#endif // USE_WEBCAM
#ifdef USE_ODROID_GO
"Odroid Go|"
#endif // USE_ODROID_GO
// "ESP32-Solo|"
// "WT32-Eth01|"
// "TTGO Watch|"
#ifdef USE_M5STACK_CORE2
"M5Stack Core2|"
#endif // USE_M5STACK_CORE2
;
// Default module settings // Default module settings
const uint8_t kModuleNiceList[] PROGMEM = { const uint8_t kModuleNiceList[] PROGMEM = {
WEMOS, WEMOS,
@ -2375,16 +2359,43 @@ const uint8_t kModuleNiceList[] PROGMEM = {
#ifdef USE_ODROID_GO #ifdef USE_ODROID_GO
ODROID_GO, ODROID_GO,
#endif // USE_ODROID_GO #endif // USE_ODROID_GO
// ESP32_SOLO, #ifdef USE_ESP32_SOLO
// WT32_ETH01, // ESP32_SOLO, // To be defined
// TTGO_WATCH, #endif // USE_ESP32_SOLO
#ifdef USE_WT32_ETH01
WT32_ETH01,
#endif // USE_WT32_ETH01
#ifdef USE_TTGO_WATCH
// TTGO_WATCH, // To be defined
#endif // USE_TTGO_WATCH
#ifdef USE_M5STACK_CORE2 #ifdef USE_M5STACK_CORE2
M5STACK_CORE2, M5STACK_CORE2,
#endif // USE_M5STACK_CORE2 #endif // USE_M5STACK_CORE2
}; };
const mytmplt kModules[] PROGMEM = const char kModuleNames[] PROGMEM =
{ "ESP32-DevKit|"
#ifdef USE_WEBCAM
"ESP32-Cam|"
#endif // USE_WEBCAM
#ifdef USE_ODROID_GO
"Odroid Go|"
#endif // USE_ODROID_GO
#ifdef USE_ESP32_SOLO
// "ESP32-Solo|" // To be defined
#endif // USE_ESP32_SOLO
#ifdef USE_WT32_ETH01
"WT32-Eth01|"
#endif // USE_WT32_ETH01
#ifdef USE_TTGO_WATCH
// "TTGO Watch|" // To be defined
#endif // USE_TTGO_WATCH
#ifdef USE_M5STACK_CORE2
"M5Stack Core2|"
#endif // USE_M5STACK_CORE2
;
const mytmplt kModules[] PROGMEM = {
{ // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32)
AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
@ -2428,6 +2439,7 @@ const mytmplt kModules[] PROGMEM =
AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
0 // Flag 0 // Flag
}, },
#ifdef USE_WEBCAM #ifdef USE_WEBCAM
{ // ESP32_CAM_AITHINKER - Any ESP32 device with webcam (ESP32) { // ESP32_CAM_AITHINKER - Any ESP32 device with webcam (ESP32)
AGPIO(GPIO_WEBCAM_XCLK), // 0 (I)O GPIO0, CAM_XCLK AGPIO(GPIO_WEBCAM_XCLK), // 0 (I)O GPIO0, CAM_XCLK
@ -2473,6 +2485,7 @@ const mytmplt kModules[] PROGMEM =
0 // Flag 0 // Flag
}, },
#endif // USE_WEBCAM #endif // USE_WEBCAM
#ifdef USE_ODROID_GO #ifdef USE_ODROID_GO
{ // ODROID_GO - (ESP32) { // ODROID_GO - (ESP32)
AGPIO(GPIO_KEY1), // 0 (I)O GPIO0, BTN-VOLUME AGPIO(GPIO_KEY1), // 0 (I)O GPIO0, BTN-VOLUME
@ -2518,6 +2531,63 @@ const mytmplt kModules[] PROGMEM =
0 // Flag 0 // Flag
}, },
#endif // USE_ODROID_GO #endif // USE_ODROID_GO
#ifdef USE_ESP32_SOLO
// { // ESP32 Solo (ESP32) - To be defined
// },
#endif // USE_ESP32_SOLO
#ifdef USE_WT32_ETH01
{ // WT32_ETH01 - (ESP32)
0, // 0 (I)O GPIO0, Ethernet EMAC_REF_CLK
AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
AGPIO(GPIO_USER), // 5 IO GPIO5, RXD Led green
// 6 IO GPIO6, Flash CLK
// 7 IO GPIO7, Flash D0
// 8 IO GPIO8, Flash D1
0, // 9 IO GPIO9, Flash D2, U1RXD
0, // 10 IO GPIO10, Flash D3, U1TXD
// 11 IO GPIO11, Flash CMD
AGPIO(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.)
0, // 13 IO GPIO13, Ethernet EMAC_RX_ER
AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
AGPIO(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.)
AGPIO(GPIO_OUTPUT_HI), // 16 IO GPIO16, Ethernet OSC_ENA
AGPIO(GPIO_LEDLNK_INV), // 17 IO GPIO17, Network link led (green)
AGPIO(GPIO_ETH_PHY_MDIO), // 18 IO GPIO18, Ethernet MDIO
0, // 19 IO GPIO19, Ethernet TXD0
0, // 20
0, // 21 IO GPIO21, Ethernet EMAC_TX_EN
0, // 22 IO LED GPIO22, Ethernet EMAC_TXD1
AGPIO(GPIO_ETH_PHY_MDC), // 23 IO GPIO23, Ethernet MDC
0, // 24
0, // 25 IO GPIO25, Ethernet EMAC_RXD0
0, // 26 IO GPIO26, Ethernet EMAC_RXD1
0, // 27 IO GPIO27, Ethernet EMAC_RX_DV
0, // 28
0, // 29
0, // 30
0, // 31
AGPIO(GPIO_USER), // 32 IO GPIO32, CFG
AGPIO(GPIO_USER), // 33 IO GPIO33, 485_EN
0, // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
0, // 37 NO PULLUP
0, // 38 NO PULLUP
AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
0 // Flag
},
#endif // USE_WT32_ETH01
#ifdef USE_TTGO_WATCH
// { // TTGO Watch (ESP32) - To be defined
// },
#endif // USE_TTGO_WATCH
#ifdef USE_M5STACK_CORE2 #ifdef USE_M5STACK_CORE2
{ // M5STACK CORE2 - (ESP32) { // M5STACK CORE2 - (ESP32)
AGPIO(GPIO_USER), // 0 (I)O GPIO0, SPKR_LRCK AGPIO(GPIO_USER), // 0 (I)O GPIO0, SPKR_LRCK

View File

@ -392,7 +392,7 @@ void ShowWebSource(uint32_t source)
{ {
if ((source > 0) && (source < SRC_MAX)) { if ((source > 0) && (source < SRC_MAX)) {
char stemp1[20]; char stemp1[20];
AddLog(LOG_LEVEL_DEBUG, PSTR("SRC: %s from %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), Webserver->client().remoteIP().toString().c_str()); AddLog(LOG_LEVEL_DEBUG, PSTR("SRC: %s from %_I"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), (uint32_t)Webserver->client().remoteIP());
} }
} }
@ -2092,7 +2092,7 @@ void HandleInformation(void)
if (static_cast<uint32_t>(EthernetLocalIP()) != 0) { if (static_cast<uint32_t>(EthernetLocalIP()) != 0) {
WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? PSTR(".local") : ""); WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? PSTR(".local") : "");
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str());
WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%s"), EthernetLocalIP().toString().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%_I"), (uint32_t)EthernetLocalIP());
WSContentSend_P(PSTR("}1<hr/>}2<hr/>")); WSContentSend_P(PSTR("}1<hr/>}2<hr/>"));
} }
#endif #endif
@ -2109,7 +2109,7 @@ void HandleInformation(void)
#endif #endif
if (static_cast<uint32_t>(WiFi.localIP()) != 0) { if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str());
WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (wifi)}2%s"), WiFi.localIP().toString().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (wifi)}2%_I"), (uint32_t)WiFi.localIP());
WSContentSend_P(PSTR("}1<hr/>}2<hr/>")); WSContentSend_P(PSTR("}1<hr/>}2<hr/>"));
} }
} }
@ -2121,8 +2121,8 @@ void HandleInformation(void)
if ((WiFi.getMode() >= WIFI_AP) && (static_cast<uint32_t>(WiFi.softAPIP()) != 0)) { if ((WiFi.getMode() >= WIFI_AP) && (static_cast<uint32_t>(WiFi.softAPIP()) != 0)) {
WSContentSend_P(PSTR("}1<hr/>}2<hr/>")); WSContentSend_P(PSTR("}1<hr/>}2<hr/>"));
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str()); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str());
WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (AP)}2%s"), WiFi.softAPIP().toString().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (AP)}2%_I"), (uint32_t)WiFi.softAPIP());
WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), WiFi.softAPIP().toString().c_str()); WSContentSend_P(PSTR("}1" D_GATEWAY "}2%_I"), (uint32_t)WiFi.softAPIP());
} }
WSContentSend_P(PSTR("}1}2&nbsp;")); // Empty line WSContentSend_P(PSTR("}1}2&nbsp;")); // Empty line
if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
@ -2975,8 +2975,8 @@ void CmndWebServer(void)
Settings.webserver = XdrvMailbox.payload; Settings.webserver = XdrvMailbox.payload;
} }
if (Settings.webserver) { if (Settings.webserver) {
Response_P(PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"), Response_P(PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %_I\"}"),
(2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str()); (2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), (uint32_t)NetworkAddress());
} else { } else {
ResponseCmndStateText(0); ResponseCmndStateText(0);
} }

View File

@ -32,6 +32,13 @@
WiFiClient EspClient; // Wifi Client - non-TLS WiFiClient EspClient; // Wifi Client - non-TLS
const char kMqttCommands[] PROGMEM = "|" // No prefix const char kMqttCommands[] PROGMEM = "|" // No prefix
// SetOption synonyms
D_SO_MQTTJSONONLY "|"
#ifdef USE_MQTT_TLS
D_SO_MQTTTLS "|"
#endif
D_SO_MQTTNORETAIN "|" D_SO_MQTTDETACHRELAY "|"
// regular commands
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT) #if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
D_CMND_MQTTFINGERPRINT "|" D_CMND_MQTTFINGERPRINT "|"
#endif #endif
@ -43,6 +50,19 @@ const char kMqttCommands[] PROGMEM = "|" // No prefix
D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|" D_CMND_MQTTLOG "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|" D_CMND_MQTTLOG "|"
D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ; D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ;
SO_SYNONYMS(kMqttSynonyms,
90,
#ifdef USE_MQTT_TLS
103,
#endif
104, 114
);
// const uint8_t kMqttSynonyms[] PROGMEM = {
// 4, // number of synonyms
// 90, 103, 104, 114,
// };
void (* const MqttCommand[])(void) PROGMEM = { void (* const MqttCommand[])(void) PROGMEM = {
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT) #if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
&CmndMqttFingerprint, &CmndMqttFingerprint,
@ -1353,7 +1373,7 @@ bool Xdrv02(uint8_t function)
break; break;
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
case FUNC_COMMAND: case FUNC_COMMAND:
result = DecodeCommand(kMqttCommands, MqttCommand); result = DecodeCommand(kMqttCommands, MqttCommand, kMqttSynonyms);
break; break;
} }
} }

View File

@ -225,9 +225,7 @@ void EnergyUpdateToday(void)
void EnergyUpdateTotal(float value, bool kwh) void EnergyUpdateTotal(float value, bool kwh)
{ {
// char energy_total_chr[FLOATSZ]; // AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total %4_f %sWh"), &value, (kwh) ? "k" : "");
// dtostrfd(value, 4, energy_total_chr);
// AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total %s %sWh"), energy_total_chr, (kwh) ? "k" : "");
uint32_t multiplier = (kwh) ? 100000 : 100; // kWh or Wh to deca milli Wh uint32_t multiplier = (kwh) ? 100000 : 100; // kWh or Wh to deca milli Wh
@ -476,9 +474,7 @@ void EnergyMarginCheck(void)
} }
else if ((1 == Energy.max_energy_state ) && (energy_daily_u >= Settings.energy_max_energy)) { else if ((1 == Energy.max_energy_state ) && (energy_daily_u >= Settings.energy_max_energy)) {
Energy.max_energy_state = 2; Energy.max_energy_state = 2;
char stemp[FLOATSZ]; ResponseTime_P(PSTR(",\"" D_JSON_MAXENERGYREACHED "\":%3_f}"), &Energy.daily);
dtostrfd(Energy.daily, 3, stemp);
ResponseTime_P(PSTR(",\"" D_JSON_MAXENERGYREACHED "\":%s}"), stemp);
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING); MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
EnergyMqttShow(); EnergyMqttShow();
SetAllPower(POWER_ALL_OFF, SRC_MAXENERGY); SetAllPower(POWER_ALL_OFF, SRC_MAXENERGY);
@ -507,9 +503,7 @@ void EnergyEverySecond(void)
if (TasmotaGlobal.global_update) { if (TasmotaGlobal.global_update) {
if (TasmotaGlobal.power && !isnan(TasmotaGlobal.temperature_celsius) && (TasmotaGlobal.temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays if (TasmotaGlobal.power && !isnan(TasmotaGlobal.temperature_celsius) && (TasmotaGlobal.temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays
char temperature[33]; AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %1_f"), &TasmotaGlobal.temperature_celsius);
dtostrfd(TasmotaGlobal.temperature_celsius, 1, temperature);
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %s"), temperature);
SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP); SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP);
} }
@ -628,25 +622,21 @@ void CmndEnergyReset(void)
} }
Energy.total = (float)(RtcSettings.energy_kWhtotal + Energy.kWhtoday_offset + Energy.kWhtoday) / 100000; Energy.total = (float)(RtcSettings.energy_kWhtotal + Energy.kWhtoday_offset + Energy.kWhtoday) / 100000;
float energy_kWhyesterday = (float)Settings.energy_kWhyesterday / 100000;
float usage1_kWhtotal = (float)Settings.energy_usage.usage1_kWhtotal / 100000;
float usage2_kWhtotal = (float)Settings.energy_usage.usage2_kWhtotal / 100000;
float return1_kWhtotal = (float)Settings.energy_usage.return1_kWhtotal / 100000;
float return2_kWhtotal = (float)Settings.energy_usage.return2_kWhtotal / 100000;
char energy_total_chr[FLOATSZ]; Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%*_f,\"" D_JSON_YESTERDAY "\":%*_f,\"" D_JSON_TODAY "\":%*_f,\"" D_JSON_USAGE "\":[%*_f,%*_f],\"" D_JSON_EXPORT "\":[%*_f,%*_f]}}"),
dtostrfd(Energy.total, Settings.flag2.energy_resolution, energy_total_chr); XdrvMailbox.command,
char energy_daily_chr[FLOATSZ]; Settings.flag2.energy_resolution, &Energy.total,
dtostrfd(Energy.daily, Settings.flag2.energy_resolution, energy_daily_chr); Settings.flag2.energy_resolution, &energy_kWhyesterday,
char energy_yesterday_chr[FLOATSZ]; Settings.flag2.energy_resolution, &Energy.daily,
dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr); Settings.flag2.energy_resolution, &usage1_kWhtotal,
Settings.flag2.energy_resolution, &usage2_kWhtotal,
char energy_usage1_chr[FLOATSZ]; Settings.flag2.energy_resolution, &return1_kWhtotal,
dtostrfd((float)Settings.energy_usage.usage1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_usage1_chr); Settings.flag2.energy_resolution, &return2_kWhtotal);
char energy_usage2_chr[FLOATSZ];
dtostrfd((float)Settings.energy_usage.usage2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_usage2_chr);
char energy_return1_chr[FLOATSZ];
dtostrfd((float)Settings.energy_usage.return1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_return1_chr);
char energy_return2_chr[FLOATSZ];
dtostrfd((float)Settings.energy_usage.return2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_return2_chr);
Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s,\"" D_JSON_USAGE "\":[%s,%s],\"" D_JSON_EXPORT "\":[%s,%s]}}"),
XdrvMailbox.command, energy_total_chr, energy_yesterday_chr, energy_daily_chr, energy_usage1_chr, energy_usage2_chr, energy_return1_chr, energy_return2_chr);
} }
void CmndTariff(void) void CmndTariff(void)

View File

@ -148,11 +148,10 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
#endif // USE_DGR_LIGHT_SEQUENCE #endif // USE_DGR_LIGHT_SEQUENCE
"|UNDOCA" ; "|UNDOCA" ;
const uint8_t kLightSynonyms[] PROGMEM = { SO_SYNONYMS(kLightSynonyms,
7, // number of entries
37, 68, 82, 91, 92, 37, 68, 82, 91, 92,
105, 106, 105, 106,
}; );
void (* const LightCommand[])(void) PROGMEM = { void (* const LightCommand[])(void) PROGMEM = {
&CmndColor, &CmndColorTemperature, &CmndDimmer, &CmndDimmerRange, &CmndDimmerStep, &CmndLedTable, &CmndFade, &CmndColor, &CmndColorTemperature, &CmndDimmer, &CmndDimmerRange, &CmndDimmerStep, &CmndLedTable, &CmndFade,
@ -252,6 +251,10 @@ struct LIGHT {
uint16_t fade_end_10[LST_MAX]; // 10 bits resolution target channel values uint16_t fade_end_10[LST_MAX]; // 10 bits resolution target channel values
uint16_t fade_duration = 0; // duration of fade in milliseconds uint16_t fade_duration = 0; // duration of fade in milliseconds
uint32_t fade_start = 0; // fade start time in milliseconds, compared to millis() uint32_t fade_start = 0; // fade start time in milliseconds, compared to millis()
bool fade_once_enabled = false; // override fade a single time
bool fade_once_value = false; // override fade a single time
bool speed_once_enabled = false; // override speed a single time
uint8_t speed_once_value = 0; // override speed a single time
uint16_t pwm_min = 0; // minimum value for PWM, from DimmerRange, 0..1023 uint16_t pwm_min = 0; // minimum value for PWM, from DimmerRange, 0..1023
uint16_t pwm_max = 1023; // maxumum value for PWM, from DimmerRange, 0..1023 uint16_t pwm_max = 1023; // maxumum value for PWM, from DimmerRange, 0..1023
@ -1608,6 +1611,16 @@ void LightSetPower(void)
LightAnimate(); LightAnimate();
} }
bool LightGetFadeSetting(void) {
if (Light.fade_once_enabled) return Light.fade_once_value;
return Settings.light_fade;
}
uint8_t LightGetSpeedSetting(void) {
if (Light.speed_once_enabled) return Light.speed_once_value;
return Settings.light_speed;
}
// On entry Light.new_color[5] contains the color to be displayed // On entry Light.new_color[5] contains the color to be displayed
// and Light.last_color[5] the color currently displayed // and Light.last_color[5] the color currently displayed
// Light.power tells which lights or channels (SetOption68) are on/off // Light.power tells which lights or channels (SetOption68) are on/off
@ -1758,12 +1771,14 @@ void LightAnimate(void)
cur_col_10[i] = orig_col_10bits[Light.color_remap[i]]; cur_col_10[i] = orig_col_10bits[Light.color_remap[i]];
} }
if (!Settings.light_fade || TasmotaGlobal.skip_light_fade || power_off || (!Light.fade_initialized)) { // no fade if (!LightGetFadeSetting() || TasmotaGlobal.skip_light_fade || power_off || (!Light.fade_initialized)) { // no fade
// record the current value for a future Fade // record the current value for a future Fade
memcpy(Light.fade_start_10, cur_col_10, sizeof(Light.fade_start_10)); memcpy(Light.fade_start_10, cur_col_10, sizeof(Light.fade_start_10));
// push the final values at 8 and 10 bits resolution to the PWMs // push the final values at 8 and 10 bits resolution to the PWMs
LightSetOutputs(cur_col_10); LightSetOutputs(cur_col_10);
Light.fade_initialized = true; // it is now ok to fade Light.fade_initialized = true; // it is now ok to fade
Light.fade_once_enabled = false; // light has been set, reset fade_once_enabled
Light.speed_once_enabled = false; // light has been set, reset speed_once_enabled
} else { // fade on } else { // fade on
if (Light.fade_running) { if (Light.fade_running) {
// if fade is running, we take the curring value as the start for the next fade // if fade is running, we take the curring value as the start for the next fade
@ -1773,6 +1788,7 @@ void LightAnimate(void)
Light.fade_running = true; Light.fade_running = true;
Light.fade_duration = 0; // set the value to zero to force a recompute Light.fade_duration = 0; // set the value to zero to force a recompute
Light.fade_start = 0; Light.fade_start = 0;
Light.fade_once_enabled = false; // fade will be applied, reset fade_once_enabled
// Fade will applied immediately below // Fade will applied immediately below
} }
} }
@ -1857,7 +1873,8 @@ bool LightApplyFade(void) { // did the value chanegd and needs to be applied
// compute the duration of the animation // compute the duration of the animation
// Note: Settings.light_speed is the number of half-seconds for a 100% fade, // Note: Settings.light_speed is the number of half-seconds for a 100% fade,
// i.e. light_speed=1 means 1024 steps in 500ms // i.e. light_speed=1 means 1024 steps in 500ms
Light.fade_duration = Settings.light_speed * 500; Light.fade_duration = LightGetSpeedSetting() * 500;
Light.speed_once_enabled = false; // The once off speed value has been read, reset it
if (!Settings.flag5.fade_fixed_duration) { if (!Settings.flag5.fade_fixed_duration) {
Light.fade_duration = (distance * Light.fade_duration) / 1023; // time is proportional to distance, except with SO117 Light.fade_duration = (distance * Light.fade_duration) / 1023; // time is proportional to distance, except with SO117
} }
@ -2835,14 +2852,23 @@ void CmndFade(void)
#ifdef USE_DEVICE_GROUPS #ifdef USE_DEVICE_GROUPS
if (XdrvMailbox.payload >= 0 && XdrvMailbox.payload <= 2) SendDeviceGroupMessage(Light.device_group_index, DGR_MSGTYP_UPDATE, DGR_ITEM_LIGHT_FADE, Settings.light_fade); if (XdrvMailbox.payload >= 0 && XdrvMailbox.payload <= 2) SendDeviceGroupMessage(Light.device_group_index, DGR_MSGTYP_UPDATE, DGR_ITEM_LIGHT_FADE, Settings.light_fade);
#endif // USE_DEVICE_GROUPS #endif // USE_DEVICE_GROUPS
#ifdef USE_LIGHT
if (!Settings.light_fade) { Light.fade_running = false; } if (!Settings.light_fade) { Light.fade_running = false; }
#endif // USE_LIGHT
ResponseCmndStateText(Settings.light_fade); ResponseCmndStateText(Settings.light_fade);
} }
void CmndSpeed(void) void CmndSpeed(void)
{ {
if (XdrvMailbox.index == 2) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 40)) {
Light.fade_once_enabled = true;
Light.fade_once_value = XdrvMailbox.payload > 0;
Light.speed_once_enabled = true;
Light.speed_once_value = XdrvMailbox.payload;
if (!Light.fade_once_value) { Light.fade_running = false; }
}
return;
}
// Speed 1 - Fast // Speed 1 - Fast
// Speed 40 - Very slow // Speed 40 - Very slow
// Speed + - Increment Speed // Speed + - Increment Speed

View File

@ -1031,7 +1031,7 @@ void Script_PollUdp(void) {
int32_t len = Script_PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE - 1); int32_t len = Script_PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE - 1);
packet_buffer[len] = 0; packet_buffer[len] = 0;
script_udp_remote_ip = Script_PortUdp.remoteIP(); script_udp_remote_ip = Script_PortUdp.remoteIP();
AddLog(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str()); AddLog(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %_I"), packet_buffer, len, (uint32_t)script_udp_remote_ip);
char *lp=packet_buffer; char *lp=packet_buffer;
if (!strncmp(lp,"=>", 2)) { if (!strncmp(lp,"=>", 2)) {
lp += 2; lp += 2;

View File

@ -181,7 +181,7 @@ int hass_tele_period = 0;
// NEW DISCOVERY // NEW DISCOVERY
const char HASS_DISCOVER_DEVICE[] PROGMEM = // Basic parameters for Discovery const char HASS_DISCOVER_DEVICE[] PROGMEM = // Basic parameters for Discovery
"{\"ip\":\"%s\"," // IP Address "{\"ip\":\"%_I\"," // IP Address
"\"dn\":\"%s\"," // Device Name "\"dn\":\"%s\"," // Device Name
"\"fn\":[%s]," // Friendly Names "\"fn\":[%s]," // Friendly Names
"\"hn\":\"%s\"," // Host Name "\"hn\":\"%s\"," // Host Name
@ -336,7 +336,7 @@ void NewHAssDiscovery(void)
// Send empty message if new discovery is disabled // Send empty message if new discovery is disabled
TasmotaGlobal.masterlog_level = 4; // Hide topic on clean and remove use weblog 4 to show it TasmotaGlobal.masterlog_level = 4; // Hide topic on clean and remove use weblog 4 to show it
if (!Settings.flag.hass_discovery) { // HassDiscoveryRelays(relays) if (!Settings.flag.hass_discovery) { // HassDiscoveryRelays(relays)
Response_P(HASS_DISCOVER_DEVICE, WiFi.localIP().toString().c_str(), SettingsText(SET_DEVICENAME), Response_P(HASS_DISCOVER_DEVICE, (uint32_t)WiFi.localIP(), SettingsText(SET_DEVICENAME),
stemp2, TasmotaGlobal.hostname, unique_id, ModuleName().c_str(), TuyaMod, iFanMod, GetStateText(0), GetStateText(1), GetStateText(2), GetStateText(3), stemp2, TasmotaGlobal.hostname, unique_id, ModuleName().c_str(), TuyaMod, iFanMod, GetStateText(0), GetStateText(1), GetStateText(2), GetStateText(3),
TasmotaGlobal.version, TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_FULLTOPIC), PSTR(SUB_PREFIX), PSTR(PUB_PREFIX), PSTR(PUB_PREFIX2), Hass.RelLst, stemp3, stemp4, TasmotaGlobal.version, TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_FULLTOPIC), PSTR(SUB_PREFIX), PSTR(PUB_PREFIX), PSTR(PUB_PREFIX2), Hass.RelLst, stemp3, stemp4,
stemp5, Settings.flag.mqtt_response, Settings.flag.button_swap, Settings.flag.button_single, Settings.flag.decimal_text, Settings.flag.not_power_linked, stemp5, Settings.flag.mqtt_response, Settings.flag.button_swap, Settings.flag.button_single, Settings.flag.decimal_text, Settings.flag.not_power_linked,
@ -1033,10 +1033,10 @@ void HAssPublishStatus(void)
{ {
Response_P(PSTR("{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\",\"" D_CMND_MODULE " or " D_CMND_TEMPLATE"\":\"%s\"," Response_P(PSTR("{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\",\"" D_CMND_MODULE " or " D_CMND_TEMPLATE"\":\"%s\","
"\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\"," "\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\","
"\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_RSSI "\":\"%d\",\"" D_JSON_SIGNAL " (dBm)""\":\"%d\"," "\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_RSSI "\":\"%d\",\"" D_JSON_SIGNAL " (dBm)""\":\"%d\","
"\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"LoadAvg\":%lu}"), "\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"LoadAvg\":%lu}"),
TasmotaGlobal.version, TasmotaGlobal.image_name, GetBuildDateAndTime().c_str(), ModuleName().c_str(), GetResetReason().c_str(), TasmotaGlobal.version, TasmotaGlobal.image_name, GetBuildDateAndTime().c_str(), ModuleName().c_str(), GetResetReason().c_str(),
GetUptime().c_str(), TasmotaGlobal.hostname, WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), GetUptime().c_str(), TasmotaGlobal.hostname, (uint32_t)WiFi.localIP(), WifiGetRssiAsQuality(WiFi.RSSI()),
WiFi.RSSI(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), TasmotaGlobal.loop_load_avg); WiFi.RSSI(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), TasmotaGlobal.loop_load_avg);
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE)); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE));
} }

View File

@ -1045,7 +1045,7 @@ void DisplayLogBufferInit(void)
DisplayLogBufferAdd(buffer); DisplayLogBufferAdd(buffer);
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), NetworkMacAddress().c_str()); snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), NetworkMacAddress().c_str());
DisplayLogBufferAdd(buffer); DisplayLogBufferAdd(buffer);
snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), NetworkAddress().toString().c_str()); snprintf_P(buffer, sizeof(buffer), PSTR("IP %_I"), (uint32_t)NetworkAddress());
DisplayLogBufferAdd(buffer); DisplayLogBufferAdd(buffer);
if (!TasmotaGlobal.global_state.wifi_down) { if (!TasmotaGlobal.global_state.wifi_down) {
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active)); snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active));

View File

@ -561,6 +561,11 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l
} else { } else {
snprintf_P(subtopic, sizeof(subtopic), PSTR("%s/%04X"), TasmotaGlobal.mqtt_topic, shortaddr); snprintf_P(subtopic, sizeof(subtopic), PSTR("%s/%04X"), TasmotaGlobal.mqtt_topic, shortaddr);
} }
if (Settings.flag5.zb_topic_endpoint) {
if (attr_list.isValidSrcEp()) {
snprintf_P(subtopic, sizeof(subtopic), PSTR("%s_%d"), subtopic, attr_list.src_ep);
}
}
char stopic[TOPSZ]; char stopic[TOPSZ];
if (Settings.flag5.zb_received_as_subtopic) if (Settings.flag5.zb_received_as_subtopic)
GetTopic_P(stopic, TELE, subtopic, json_prefix); GetTopic_P(stopic, TELE, subtopic, json_prefix);

View File

@ -132,7 +132,7 @@ const char kZigbeeStarted[] PROGMEM = D_LOG_ZIGBEE "Zigbee started";
const char kResetting[] PROGMEM = "Resetting configuration"; const char kResetting[] PROGMEM = "Resetting configuration";
const char kResettingDevice[] PROGMEM = D_LOG_ZIGBEE "Resetting EZSP device"; const char kResettingDevice[] PROGMEM = D_LOG_ZIGBEE "Resetting EZSP device";
const char kReconfiguringDevice[] PROGMEM = D_LOG_ZIGBEE "Factory reset EZSP device"; const char kReconfiguringDevice[] PROGMEM = D_LOG_ZIGBEE "Factory reset EZSP device";
const char kZNP12[] PROGMEM = "Only ZNP 1.2 is currently supported"; const char kZNP123[] PROGMEM = "Only ZNP 1.2 and 3.x are currently supported";
const char kEZ8[] PROGMEM = "Only EZSP protocol v8 is currently supported"; const char kEZ8[] PROGMEM = "Only EZSP protocol v8 is currently supported";
const char kAbort[] PROGMEM = "Abort"; const char kAbort[] PROGMEM = "Abort";
const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort"; const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort";
@ -194,6 +194,7 @@ ZBM(ZBS_LOGTYPE_DEVICE, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CON
// Write configuration - write success // Write configuration - write success
ZBM(ZBR_W_OK, Z_SRSP | Z_SAPI, SAPI_WRITE_CONFIGURATION, Z_SUCCESS ) // 660500 - Write Configuration ZBM(ZBR_W_OK, Z_SRSP | Z_SAPI, SAPI_WRITE_CONFIGURATION, Z_SUCCESS ) // 660500 - Write Configuration
ZBM(ZBR_WNV_OK, Z_SRSP | Z_SYS, SYS_OSAL_NV_WRITE, Z_SUCCESS ) // 610900 - NV Write ZBM(ZBR_WNV_OK, Z_SRSP | Z_SYS, SYS_OSAL_NV_WRITE, Z_SUCCESS ) // 610900 - NV Write
ZBM(ZBR_WNV_OKE, Z_SRSP | Z_SYS, SYS_OSAL_NV_WRITE ) // 6109xx - NV Write, OK or error
// Factory reset // Factory reset
ZBM(ZBS_FACTRES, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x03 ) // 2605030103 ZBM(ZBS_FACTRES, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x03 ) // 2605030103
@ -415,7 +416,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
// Z_ZDO:startupFromApp // Z_ZDO:startupFromApp
//ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "starting zigbee coordinator") //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "starting zigbee coordinator")
ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator
ZI_WAIT_RECV(2000, ZBR_STARTUPFROMAPP) // wait for sync ack of command ZI_WAIT_RECV(5000, ZBR_STARTUPFROMAPP) // wait for sync ack of command
ZI_WAIT_UNTIL_FUNC(10000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started ZI_WAIT_UNTIL_FUNC(10000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started
ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo
ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &ZNP_ReceiveDeviceInfo) ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &ZNP_ReceiveDeviceInfo)
@ -472,7 +473,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_SEND(ZBS_W_PFGKEN) // write PRECFGKEY Enable ZI_SEND(ZBS_W_PFGKEN) // write PRECFGKEY Enable
ZI_WAIT_RECV(1000, ZBR_W_OK) ZI_WAIT_RECV(1000, ZBR_W_OK)
ZI_SEND(ZBS_WNV_SECMODE) // write Security Mode ZI_SEND(ZBS_WNV_SECMODE) // write Security Mode
ZI_WAIT_RECV(1000, ZBR_WNV_OK) ZI_WAIT_RECV(1000, ZBR_WNV_OKE) // Tolerate error for ZNP 3.x
ZI_SEND(ZBS_W_ZDODCB) // write Z_ZDO Direct CB ZI_SEND(ZBS_W_ZDODCB) // write Z_ZDO Direct CB
ZI_WAIT_RECV(1000, ZBR_W_OK) ZI_WAIT_RECV(1000, ZBR_W_OK)
// Now mark the device as ready, writing 0x55 in memory slot 0x0F00 // Now mark the device as ready, writing 0x55 in memory slot 0x0F00
@ -558,7 +559,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
// Error: version of Z-Stack is not supported // Error: version of Z-Stack is not supported
ZI_LABEL(ZIGBEE_LABEL_UNSUPPORTED_VERSION) ZI_LABEL(ZIGBEE_LABEL_UNSUPPORTED_VERSION)
ZI_MQTT_STATE(ZIGBEE_STATUS_UNSUPPORTED_VERSION, kZNP12) ZI_MQTT_STATE(ZIGBEE_STATUS_UNSUPPORTED_VERSION, kZNP123)
ZI_GOTO(ZIGBEE_LABEL_ABORT) ZI_GOTO(ZIGBEE_LABEL_ABORT)
// Abort state machine, general error // Abort state machine, general error

View File

@ -372,8 +372,8 @@ int32_t ZNP_Reboot(int32_t res, SBuffer &buf) {
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
if ((0x02 == major_rel) && (0x06 == minor_rel)) { if ((0x02 == major_rel) && ((0x06 == minor_rel) || (0x07 == minor_rel))) {
return 0; // version 2.6.x is ok return 0; // version 2.6.x and 2.7.x are ok
} else { } else {
return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort
} }
@ -403,8 +403,8 @@ int32_t ZNP_ReceiveCheckVersion(int32_t res, SBuffer &buf) {
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE));
if ((0x02 == major_rel) && (0x06 == minor_rel)) { if ((0x02 == major_rel) && ((0x06 == minor_rel) || (0x07 == minor_rel))) {
return 0; // version 2.6.x is ok return 0; // version 2.6.x and 2.7.x are ok
} else { } else {
return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort
} }

View File

@ -26,7 +26,7 @@
const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
// SetOption synonyms // SetOption synonyms
D_SO_ZIGBEE_NAMEKEY "|" D_SO_ZIGBEE_DEVICETOPIC "|" D_SO_ZIGBEE_NOPREFIX "|" D_SO_ZIGBEE_ENDPOINTSUFFIX "|" D_SO_ZIGBEE_NOAUTOBIND "|" D_SO_ZIGBEE_NAMEKEY "|" D_SO_ZIGBEE_DEVICETOPIC "|" D_SO_ZIGBEE_NOPREFIX "|" D_SO_ZIGBEE_ENDPOINTSUFFIX "|" D_SO_ZIGBEE_NOAUTOBIND "|"
D_SO_ZIGBEE_NAMETOPIC "|" D_SO_ZIGBEE_NAMETOPIC "|" D_SO_ZIGBEE_ENDPOINTTOPIC "|" D_SO_ZIGBEE_NOAUTOBIND "|" D_SO_ZIGBEE_ZBRECEIVEDTOPIC "|" D_SO_ZIGBEE_OMITDEVICE "|"
#ifdef USE_ZIGBEE_ZNP #ifdef USE_ZIGBEE_ZNP
D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|" D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|"
#endif // USE_ZIGBEE_ZNP #endif // USE_ZIGBEE_ZNP
@ -42,11 +42,10 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA
; ;
const uint8_t kZbSynonyms[] PROGMEM = { SO_SYNONYMS(kZbSynonyms,
6, // number of synonyms
83, 89, 100, 101, 110, 83, 89, 100, 101, 110,
112, 112, 120, 116, 118, 119,
}; );
void (* const ZigbeeCommand[])(void) PROGMEM = { void (* const ZigbeeCommand[])(void) PROGMEM = {
#ifdef USE_ZIGBEE_ZNP #ifdef USE_ZIGBEE_ZNP

View File

@ -32,44 +32,41 @@ struct BUZZER {
uint8_t inverted = 0; // Buzzer inverted flag (1 = (0 = On, 1 = Off)) uint8_t inverted = 0; // Buzzer inverted flag (1 = (0 = On, 1 = Off))
uint8_t count = 0; // Number of buzzes uint8_t count = 0; // Number of buzzes
uint8_t mode = 0; // Buzzer mode (0 = regular, 1 = infinite, 2 = follow LED) uint8_t mode = 0; // Buzzer mode (0 = regular, 1 = infinite, 2 = follow LED)
uint8_t freq_mode = 0; // Output mode (0 = regular, 1 = using frequency output)
uint8_t set[2]; uint8_t set[2];
uint8_t duration; uint8_t duration;
uint8_t state = 0; uint8_t state = 0;
uint8_t tune_size = 0;
uint8_t size = 0;
} Buzzer; } Buzzer;
/*********************************************************************************************/ /*********************************************************************************************/
void BuzzerSet(uint8_t state) void BuzzerSet(uint32_t state) {
{
if (Buzzer.inverted) { if (Buzzer.inverted) {
state = !state; state = !state;
} }
if (Buzzer.freq_mode == 1) { if (Settings.flag4.buzzer_freq_mode) { // SetOption111 - Enable frequency output mode for buzzer
static uint8_t last_state = 0; static uint8_t last_state = 0;
if (last_state != state) { if (last_state != state) {
if (state) { // Set 50% duty cycle for frequency output
analogWrite(Pin(GPIO_BUZZER, 0), Settings.pwm_range / 2); // set 50% duty cycle for frequency output // Set 0% (or 100% for inverted PWM) duty cycle which turns off frequency output either way
} analogWrite(Pin(GPIO_BUZZER), (state) ? Settings.pwm_range / 2 : 0); // set duty cycle for frequency output
else {
analogWrite(Pin(GPIO_BUZZER, 0), 0); // set 0% (or 100% for inverted PWM) duty cycle which turns off frequency output either way
}
last_state = state; last_state = state;
} }
} } else {
else {
DigitalWrite(GPIO_BUZZER, 0, state); // Buzzer On/Off DigitalWrite(GPIO_BUZZER, 0, state); // Buzzer On/Off
} }
} }
//void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0, uint32_t mode = 0); //void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0, uint32_t mode = 0);
void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32_t mode) void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32_t mode) {
{ Buzzer.set[0] = off; // Off duration in 100 mSec steps
Buzzer.set[0] = off; // off duration in 100 mSec steps Buzzer.set[1] = on; // On duration in 100 mSec steps
Buzzer.set[1] = on; // on duration in 100 mSec steps
Buzzer.duration = 1; // Start buzzer on first step Buzzer.duration = 1; // Start buzzer on first step
Buzzer.size = 0;
Buzzer.tune_size = 0;
Buzzer.tune = 0;
Buzzer.tune_reload = 0; Buzzer.tune_reload = 0;
Buzzer.mode = mode; Buzzer.mode = mode;
@ -80,54 +77,45 @@ void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32
if (!(tune2 & 0x80000000)) { if (!(tune2 & 0x80000000)) {
tune2 <<= 1; // Skip leading silence tune2 <<= 1; // Skip leading silence
} else { } else {
Buzzer.tune_size++; // Allow trailing silence
Buzzer.tune_reload <<= 1; // Add swapped tune Buzzer.tune_reload <<= 1; // Add swapped tune
Buzzer.tune_reload |= tune1 & 1; Buzzer.tune_reload |= tune1 & 1;
tune1 >>= 1; tune1 >>= 1;
} }
} }
Buzzer.size = Buzzer.tune_size;
Buzzer.tune = Buzzer.tune_reload; Buzzer.tune = Buzzer.tune_reload;
} }
Buzzer.count = count * 2; // Start buzzer Buzzer.count = count * 2; // Start buzzer
// We can use PWM mode for buzzer output if enabled. AddLog(LOG_LEVEL_DEBUG, PSTR("BUZ: Count %d(%d), Time %d/%d, Tune 0x%08X(0x%08X), Size %d, Mode %d"),
if (Settings.flag4.buzzer_freq_mode) { // SetOption111 - Enable frequency output mode for buzzer count, Buzzer.count, on, off, tune, Buzzer.tune, Buzzer.tune_size, Settings.flag4.buzzer_freq_mode);
Buzzer.freq_mode = 1;
}
else {
Buzzer.freq_mode = 0;
}
AddLog(LOG_LEVEL_DEBUG, PSTR("BUZ: %d(%d),%d,%d,0x%08X(0x%08X),%d"), count, Buzzer.count, on, off, tune, Buzzer.tune, Buzzer.freq_mode);
Buzzer.enable = (Buzzer.count > 0); Buzzer.enable = (Buzzer.count > 0);
if (Buzzer.enable) { if (Buzzer.enable) {
if (Settings.sleep > PWM_MAX_SLEEP) { if (Settings.sleep > PWM_MAX_SLEEP) {
TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maxumum value of 10 milliseconds to ensure that buzzer periods are a bit more accurate TasmotaGlobal.sleep = PWM_MAX_SLEEP; // Set a maxumum value of 10 milliseconds to ensure that buzzer periods are a bit more accurate
} else { } else {
TasmotaGlobal.sleep = Settings.sleep; // or keep the current sleep if it's lower than 10 TasmotaGlobal.sleep = Settings.sleep; // Or keep the current sleep if it's lower than 10
} }
} } else {
else { TasmotaGlobal.sleep = Settings.sleep; // Restore original sleep
TasmotaGlobal.sleep = Settings.sleep; // restore original sleep
BuzzerSet(0); BuzzerSet(0);
} }
} }
void BuzzerSetStateToLed(uint32_t state) void BuzzerSetStateToLed(uint32_t state) {
{
if (Buzzer.enable && (2 == Buzzer.mode)) { if (Buzzer.enable && (2 == Buzzer.mode)) {
Buzzer.state = (state != 0); Buzzer.state = (state != 0);
BuzzerSet(Buzzer.state); BuzzerSet(Buzzer.state);
} }
} }
void BuzzerBeep(uint32_t count) void BuzzerBeep(uint32_t count) {
{
BuzzerBeep(count, 1, 1, 0, 0); BuzzerBeep(count, 1, 1, 0, 0);
} }
void BuzzerEnabledBeep(uint32_t count, uint32_t duration) void BuzzerEnabledBeep(uint32_t count, uint32_t duration) {
{
if (Settings.flag3.buzzer_enable) { // SetOption67 - Enable buzzer when available if (Settings.flag3.buzzer_enable) { // SetOption67 - Enable buzzer when available
BuzzerBeep(count, duration, 1, 0, 0); BuzzerBeep(count, duration, 1, 0, 0);
} }
@ -135,8 +123,7 @@ void BuzzerEnabledBeep(uint32_t count, uint32_t duration)
/*********************************************************************************************/ /*********************************************************************************************/
bool BuzzerPinState(void) bool BuzzerPinState(void) {
{
if (XdrvMailbox.index == AGPIO(GPIO_BUZZER_INV)) { if (XdrvMailbox.index == AGPIO(GPIO_BUZZER_INV)) {
Buzzer.inverted = 1; Buzzer.inverted = 1;
XdrvMailbox.index -= (AGPIO(GPIO_BUZZER_INV) - AGPIO(GPIO_BUZZER)); XdrvMailbox.index -= (AGPIO(GPIO_BUZZER_INV) - AGPIO(GPIO_BUZZER));
@ -145,8 +132,7 @@ bool BuzzerPinState(void)
return false; return false;
} }
void BuzzerInit(void) void BuzzerInit(void) {
{
if (PinUsed(GPIO_BUZZER)) { if (PinUsed(GPIO_BUZZER)) {
pinMode(Pin(GPIO_BUZZER), OUTPUT); pinMode(Pin(GPIO_BUZZER), OUTPUT);
BuzzerSet(0); BuzzerSet(0);
@ -155,17 +141,18 @@ void BuzzerInit(void)
} }
} }
void BuzzerEvery100mSec(void) void BuzzerEvery100mSec(void) {
{
if (Buzzer.enable && (Buzzer.mode != 2)) { if (Buzzer.enable && (Buzzer.mode != 2)) {
if (Buzzer.count) { if (Buzzer.count) {
if (Buzzer.duration) { if (Buzzer.duration) {
Buzzer.duration--; Buzzer.duration--;
if (!Buzzer.duration) { if (!Buzzer.duration) {
if (Buzzer.tune) { if (Buzzer.size) {
Buzzer.size--;
Buzzer.state = Buzzer.tune & 1; Buzzer.state = Buzzer.tune & 1;
Buzzer.tune >>= 1; Buzzer.tune >>= 1;
} else { } else {
Buzzer.size = Buzzer.tune_size;
Buzzer.tune = Buzzer.tune_reload; Buzzer.tune = Buzzer.tune_reload;
Buzzer.count -= (Buzzer.tune_reload) ? 2 : 1; Buzzer.count -= (Buzzer.tune_reload) ? 2 : 1;
Buzzer.state = Buzzer.count & 1; Buzzer.state = Buzzer.count & 1;
@ -187,14 +174,17 @@ void BuzzerEvery100mSec(void)
* Commands * Commands
\*********************************************************************************************/ \*********************************************************************************************/
const char kBuzzerCommands[] PROGMEM = "|" // No prefix const char kBuzzerCommands[] PROGMEM = "Buzzer|" // Prefix
"Buzzer" ; "Active|Pwm||" ;
SO_SYNONYMS(kBuzzerSynonyms,
67, 111
);
void (* const BuzzerCommand[])(void) PROGMEM = { void (* const BuzzerCommand[])(void) PROGMEM = {
&CmndBuzzer }; &CmndBuzzer };
void CmndBuzzer(void) void CmndBuzzer(void) {
{
// Buzzer <number of beeps>,<duration of beep in 100mS steps>,<duration of silence in 100mS steps>,<tune> // Buzzer <number of beeps>,<duration of beep in 100mS steps>,<duration of silence in 100mS steps>,<tune>
// All parameters are optional // All parameters are optional
// //
@ -203,7 +193,8 @@ void CmndBuzzer(void)
// Buzzer 2 = Beep twice with duration 200mS and pause 100mS // Buzzer 2 = Beep twice with duration 200mS and pause 100mS
// Buzzer 2,3 = Beep twice with duration 300mS and pause 100mS // Buzzer 2,3 = Beep twice with duration 300mS and pause 100mS
// Buzzer 2,3,4 = Beep twice with duration 300mS and pause 400mS // Buzzer 2,3,4 = Beep twice with duration 300mS and pause 400mS
// Buzzer 2,3,4,0xF54 = Beep a sequence twice indicated by 0xF54 = 1111 0101 01 with duration 300mS and pause 400mS // Buzzer 2,3,4,0x0F54 = Beep a sequence twice indicated by 0x0F54 = 1111 0101 0100 with duration 300mS and pause 400mS
// Notice skipped leading zeroes but valid trailing zeroes
// Buzzer -1 = Beep infinite // Buzzer -1 = Beep infinite
// Buzzer -2 = Beep following link led // Buzzer -2 = Beep following link led
@ -233,8 +224,7 @@ void CmndBuzzer(void)
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
bool Xdrv24(uint8_t function) bool Xdrv24(uint8_t function) {
{
bool result = false; bool result = false;
if (Buzzer.active) { if (Buzzer.active) {
@ -243,7 +233,7 @@ bool Xdrv24(uint8_t function)
BuzzerEvery100mSec(); BuzzerEvery100mSec();
break; break;
case FUNC_COMMAND: case FUNC_COMMAND:
result = DecodeCommand(kBuzzerCommands, BuzzerCommand); result = DecodeCommand(kBuzzerCommands, BuzzerCommand, kBuzzerSynonyms);
break; break;
case FUNC_PRE_INIT: case FUNC_PRE_INIT:
BuzzerInit(); BuzzerInit();

View File

@ -619,13 +619,13 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
if (mqtt_trigger) { if (mqtt_trigger) {
char topic[TOPSZ]; char topic[TOPSZ];
sprintf_P(TasmotaGlobal.mqtt_data, PSTR("Trigger%u"), mqtt_trigger); sprintf_P(TasmotaGlobal.mqtt_data, PSTR("Trigger%u"), mqtt_trigger);
#ifdef USE_PWM_DIMMER_REMOTE #ifdef USE_DEVICE_GROUPS
if (Settings.flag4.multiple_device_groups) { if (Settings.flag4.device_groups_enabled) {
snprintf_P(topic, sizeof(topic), PSTR("cmnd/%s/EVENT"), device_groups[power_button_index].group_name); snprintf_P(topic, sizeof(topic), PSTR("cmnd/%s/EVENT"), device_groups[power_button_index].group_name);
MqttPublish(topic); MqttPublish(topic);
} }
else else
#endif // USE_PWM_DIMMER_REMOTE #endif // USE_DEVICE_GROUPS
MqttPublishPrefixTopic_P(CMND, PSTR("EVENT")); MqttPublishPrefixTopic_P(CMND, PSTR("EVENT"));
} }

View File

@ -413,7 +413,7 @@ const char UFS_FORM_FILE_UPGc[] PROGMEM =
"<div style='text-align:left;color:#%06x;'>" D_FS_SIZE " %s MB - " D_FS_FREE " %s MB"; "<div style='text-align:left;color:#%06x;'>" D_FS_SIZE " %s MB - " D_FS_FREE " %s MB";
const char UFS_FORM_FILE_UPGc1[] PROGMEM = const char UFS_FORM_FILE_UPGc1[] PROGMEM =
" &nbsp;&nbsp;<a href='http://%s/ufsd?dir=%d'>%s</a>"; " &nbsp;&nbsp;<a href='http://%_I/ufsd?dir=%d'>%s</a>";
const char UFS_FORM_FILE_UPGc2[] PROGMEM = const char UFS_FORM_FILE_UPGc2[] PROGMEM =
"</div>"; "</div>";
@ -436,11 +436,11 @@ const char UFS_FORM_SDC_DIRd[] PROGMEM =
const char UFS_FORM_SDC_DIRb[] PROGMEM = const char UFS_FORM_SDC_DIRb[] PROGMEM =
"<pre><a href='%s' file='%s'>%s</a> %s %8d %s</pre>"; "<pre><a href='%s' file='%s'>%s</a> %s %8d %s</pre>";
const char UFS_FORM_SDC_HREF[] PROGMEM = const char UFS_FORM_SDC_HREF[] PROGMEM =
"http://%s/ufsd?download=%s/%s"; "http://%_I/ufsd?download=%s/%s";
#ifdef GUI_TRASH_FILE #ifdef GUI_TRASH_FILE
const char UFS_FORM_SDC_HREFdel[] PROGMEM = const char UFS_FORM_SDC_HREFdel[] PROGMEM =
//"<a href=http://%s/ufsd?delete=%s/%s>&#128465;</a>"; //"<a href=http://%_I/ufsd?delete=%s/%s>&#128465;</a>";
"<a href=http://%s/ufsd?delete=%s/%s>&#128293;</a>"; // 🔥 "<a href=http://%_I/ufsd?delete=%s/%s>&#128293;</a>"; // 🔥
#endif // GUI_TRASH_FILE #endif // GUI_TRASH_FILE
void UfsDirectory(void) { void UfsDirectory(void) {
@ -492,7 +492,7 @@ void UfsDirectory(void) {
WSContentSend_PD(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs); WSContentSend_PD(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs);
if (ufs_dir) { if (ufs_dir) {
WSContentSend_P(UFS_FORM_FILE_UPGc1, WiFi.localIP().toString().c_str(), (ufs_dir == 1)?2:1, (ufs_dir == 1)?PSTR("SDCard"):PSTR("FlashFS")); WSContentSend_P(UFS_FORM_FILE_UPGc1, (uint32_t)WiFi.localIP(), (ufs_dir == 1)?2:1, (ufs_dir == 1)?PSTR("SDCard"):PSTR("FlashFS"));
} }
WSContentSend_P(UFS_FORM_FILE_UPGc2); WSContentSend_P(UFS_FORM_FILE_UPGc2);
@ -520,7 +520,7 @@ void UfsListDir(char *path, uint8_t depth) {
if (dir) { if (dir) {
dir.rewindDirectory(); dir.rewindDirectory();
if (strlen(path)>1) { if (strlen(path)>1) {
snprintf_P(npath, sizeof(npath), PSTR("http://%s/ufsd?download=%s"), WiFi.localIP().toString().c_str(), path); ext_snprintf_P(npath, sizeof(npath), PSTR("http://%_I/ufsd?download=%s"), (uint32_t)WiFi.localIP(), path);
for (uint32_t cnt = strlen(npath) - 1; cnt > 0; cnt--) { for (uint32_t cnt = strlen(npath) - 1; cnt > 0; cnt--) {
if (npath[cnt] == '/') { if (npath[cnt] == '/') {
if (npath[cnt - 1] == '=') { if (npath[cnt - 1] == '=') {
@ -562,7 +562,7 @@ void UfsListDir(char *path, uint8_t depth) {
sprintf(cp, format, ep); sprintf(cp, format, ep);
if (entry.isDirectory()) { if (entry.isDirectory()) {
snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, WiFi.localIP().toString().c_str(), pp, ep); snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, (uint32_t)WiFi.localIP(), pp, ep);
WSContentSend_P(UFS_FORM_SDC_DIRd, npath, ep, name); WSContentSend_P(UFS_FORM_SDC_DIRd, npath, ep, name);
uint8_t plen = strlen(path); uint8_t plen = strlen(path);
if (plen > 1) { if (plen > 1) {
@ -574,12 +574,12 @@ void UfsListDir(char *path, uint8_t depth) {
} else { } else {
#ifdef GUI_TRASH_FILE #ifdef GUI_TRASH_FILE
char delpath[128]; char delpath[128];
snprintf_P(delpath, sizeof(delpath), UFS_FORM_SDC_HREFdel, WiFi.localIP().toString().c_str(), pp, ep); snprintf_P(delpath, sizeof(delpath), UFS_FORM_SDC_HREFdel, (uint32_t)WiFi.localIP(), pp, ep);
#else #else
char delpath[2]; char delpath[2];
delpath[0]=0; delpath[0]=0;
#endif // GUI_TRASH_FILE #endif // GUI_TRASH_FILE
snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, WiFi.localIP().toString().c_str(), pp, ep); snprintf_P(npath, sizeof(npath), UFS_FORM_SDC_HREF, (uint32_t)WiFi.localIP(), pp, ep);
WSContentSend_P(UFS_FORM_SDC_DIRb, npath, ep, name, tstr.c_str(), entry.size(), delpath); WSContentSend_P(UFS_FORM_SDC_DIRb, npath, ep, name, tstr.c_str(), entry.size(), delpath);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
xdrv_52_BLE_ESP32.ino - BLE via ESP32 support for Tasmota xdrv_79_esp32_ble.ino - BLE via ESP32 support for Tasmota
Copyright (C) 2020 Christian Baars and Theo Arends and Simon Hailes Copyright (C) 2020 Christian Baars and Theo Arends and Simon Hailes
@ -22,8 +22,18 @@
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
*/ */
// TEMPORARILY define ESP32 and USE_BLE_ESP32 so VSCODE shows highlighting....
//#define VSCODE_DEV
#ifdef VSCODE_DEV
#define ESP32
#define USE_BLE_ESP32
#endif
#ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support
#ifdef USE_BLE_ESP32
/* /*
xdrv_52: xdrv_79:
This driver uses the ESP32 BLE functionality to hopefully provide enough This driver uses the ESP32 BLE functionality to hopefully provide enough
BLE functionality to implement specific drivers on top of it. BLE functionality to implement specific drivers on top of it.
@ -35,34 +45,26 @@
connect/read/awaitnotify from a MAC/Service/Characteristic/NotifyCharacteristic connect/read/awaitnotify from a MAC/Service/Characteristic/NotifyCharacteristic
Cmnds: Cmnds:
BLEOp0 - requests status of operations BLEPeriod
BLEOp1 MAC - create an operation in preparation, and populate it's MAC address BLEAdv
BLEOp2 Service - add a serviceUUID to the operation in preparation BLEOp
BLEOp3 Characteristic - add a CharacteristicUUID to the operation in preparation for read/write BLEMode
BLEOp4 writedata - optional:add data to write to the operation in preparation - hex string BLEDetails
BLEOp5 - optional:signify that a read should be done BLEScan
BLEOp6 NotifyCharacteristic - optional:add a NotifyCharacteristicUUID to the operation in preparation to wait for a notify BLEAlias
BLEOp9 - publish the 'operation in preparation' to MQTT. BLEName
BLEOp10 - add the 'operation in preparation' to the queue of operations to perform. BLEDebug
BLEDevices
BLEMaxAge
BLEAddrFilter
Other drivers can add callbacks to receive advertisements Other drivers can add callbacks to receive advertisements
Other drivers can add 'operations' to be performed and receive callbacks from the operation's success or failure Other drivers can add 'operations' to be performed and receive callbacks from the operation's success or failure
Example: Example BLEOp:
Write and request next notify: Write and request next notify:
backlog BLEOp1 001A22092EE0; BLEOp2 3e135142-654f-9090-134a-a6ff5bb77046; BLEOp3 3fa4585a-ce4a-3bad-db4b-b8df8179ea09; BLEOp4 03; BLEOp6 d0e8434d-cd29-0996-af41-6c90f4e0eb2a; BLEOp M:4C65A8DAF43A s:00001530-1212-efde-1523-785feabcd123 n:00001531-1212-efde-1523-785feabcd123 c:00001531-1212-efde-1523-785feabcd123 w:00 go
BLEOp10 -> 12:45:12 MQT: tele/tasmota_esp32/BLE = {"BLEOperation":{"opid":"11","stat":"7","state":"DONENOTIFIED","MAC":"4C65A8DAF43A","svc":"00001530-1212-efde-1523-785feabcd123","char":"00001531-1212-efde-1523-785feabcd123","notifychar":"00001531-1212-efde-1523-785feabcd123","write":"00","notify":"100003"}}
19:25:08 RSL: tele/tasmota_E89E98/SENSOR = {"BLEOperation":{"opid":"3,"state":"1,"MAC":"001A22092EE0","svc":"3e135142-654f-9090-134a-a6ff5bb77046","char":"3fa4585a-ce4a-3bad-db4b-b8df8179ea09","wrote":"03}}
19:25:08 queued 0 sent {"BLEOperation":{"opid":"3,"state":"1,"MAC":"001A22092EE0","svc":"3e135142-654f-9090-134a-a6ff5bb77046","char":"3fa4585a-ce4a-3bad-db4b-b8df8179ea09","wrote":"03}}
19:25:08 RSL: stat/tasmota_E89E98/RESULT = {"BLEOp":"Done"}
.....
19:25:11 RSL: tele/tasmota_E89E98/SENSOR = {"BLEOperation":{"opid":"3,"state":"11,"MAC":"001A22092EE0","svc":"3e135142-654f-9090-134a-a6ff5bb77046","char":"3fa4585a-ce4a-3bad-db4b-b8df8179ea09","wrote":"03","notify":"020109000428}}
state: 1 -> starting,
7 -> read complete
8 -> write complete
11 -> notify complete
-ve + -> failure (see GEN_STATE_FAILED_XXXX constants below.)
The driver can also be used by other drivers, using the functions: The driver can also be used by other drivers, using the functions:
@ -80,27 +82,12 @@ i.e. the Bluetooth of the ESP can be shared without conflict.
*/ */
// TEMPORARILY define ESP32 and USE_BLE_ESP32 so VSCODE shows highlighting....
//#define VSCODE_DEV
#ifdef VSCODE_DEV
#define ESP32
#define USE_BLE_ESP32
#endif
#ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support
#ifdef USE_BLE_ESP32
#define BLE_ESP32_ALIASES #define BLE_ESP32_ALIASES
// uncomment for more diagnostic/information messages - + more flash use. // uncomment for more diagnostic/information messages - + more flash use.
//#define BLE_ESP32_DEBUG //#define BLE_ESP32_DEBUG
#define XDRV_79 79
#define XDRV_52 52
#define USE_MI_DECRYPTION #define USE_MI_DECRYPTION
#include <vector> #include <vector>
@ -3456,7 +3443,7 @@ int ExtStopBLE(){
return 0; return 0;
} }
bool Xdrv52(uint8_t function) bool Xdrv79(uint8_t function)
{ {
//if (!Settings.flag5.mi32_enable) { return false; } // SetOption115 - Enable ESP32 BLE BLE //if (!Settings.flag5.mi32_enable) { return false; } // SetOption115 - Enable ESP32 BLE BLE

View File

@ -1,7 +1,7 @@
/* /*
xdrv_81_webcam.ino - ESP32 webcam support for Tasmota xdrv_81_esp32_odroidgo.ino - ESP32 odroid go support for Tasmota
Copyright (C) 2021 Gerhard Mutz and Theo Arends Copyright (C) 2021 Theo Arends
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* /*
xdrv_81_webcam.ino - ESP32 webcam support for Tasmota xdrv_81_esp32_webcam.ino - ESP32 webcam support for Tasmota
Copyright (C) 2021 Gerhard Mutz and Theo Arends Copyright (C) 2021 Gerhard Mutz and Theo Arends
@ -918,8 +918,8 @@ void WcShowStream(void) {
delay(50); // Give the webcam webserver some time to prepare the stream delay(50); // Give the webcam webserver some time to prepare the stream
} }
if (Wc.CamServer && Wc.up) { if (Wc.CamServer && Wc.up) {
WSContentSend_P(PSTR("<p></p><center><img src='http://%s:81/stream' alt='Webcam stream' style='width:99%%;'></center><p></p>"), WSContentSend_P(PSTR("<p></p><center><img src='http://%_I:81/stream' alt='Webcam stream' style='width:99%%;'></center><p></p>"),
WiFi.localIP().toString().c_str()); (uint32_t)WiFi.localIP());
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
xdrv_82_ethernet.ino - ESP32 (PoE) ethernet support for Tasmota xdrv_82_esp32_ethernet.ino - ESP32 (PoE) ethernet support for Tasmota
Copyright (C) 2021 Theo Arends Copyright (C) 2021 Theo Arends
@ -93,8 +93,8 @@ void EthernetEvent(WiFiEvent_t event) {
ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : ""); ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "");
break; break;
case SYSTEM_EVENT_ETH_GOT_IP: case SYSTEM_EVENT_ETH_GOT_IP:
AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"), AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %_I, Hostname %s"),
ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname); ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname);
Settings.ipv4_address[1] = (uint32_t)ETH.gatewayIP(); Settings.ipv4_address[1] = (uint32_t)ETH.gatewayIP();
Settings.ipv4_address[2] = (uint32_t)ETH.subnetMask(); Settings.ipv4_address[2] = (uint32_t)ETH.subnetMask();
Settings.ipv4_address[3] = (uint32_t)ETH.dnsIP(); Settings.ipv4_address[3] = (uint32_t)ETH.dnsIP();
@ -120,6 +120,12 @@ void EthernetInit(void) {
return; return;
} }
if (WT32_ETH01 == TasmotaGlobal.module_type) {
Settings.eth_address = 1; // EthAddress
Settings.eth_type = ETH_PHY_LAN8720; // EthType
Settings.eth_clk_mode = ETH_CLOCK_GPIO0_IN; // EthClockMode
}
// snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), TasmotaGlobal.hostname); // snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), TasmotaGlobal.hostname);
strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_eth" strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_eth"
strcat(eth_hostname, "_eth"); strcat(eth_hostname, "_eth");

View File

@ -1,5 +1,5 @@
/* /*
xdrv_83_esp32watch.ino - ESP32 TTGO watch support for Tasmota xdrv_83_esp32_watch.ino - ESP32 TTGO watch support for Tasmota
Copyright (C) 2021 Gerhard Mutz and Theo Arends Copyright (C) 2021 Gerhard Mutz and Theo Arends

View File

@ -1,5 +1,5 @@
/* /*
xdrv_84_core2.ino - ESP32 m5stack core2 support for Tasmota xdrv_84_esp32_core2.ino - ESP32 m5stack core2 support for Tasmota
Copyright (C) 2021 Gerhard Mutz and Theo Arends Copyright (C) 2021 Gerhard Mutz and Theo Arends

View File

@ -25,11 +25,11 @@
#define XLGT_05 5 #define XLGT_05 5
//#define SONOFF_L1_START_DELAY // Sync Nuvotron power state with Tasmota on power up #define SONOFF_L1_START_DELAY // Sync Nuvotron power state with Tasmota on power up
//#define SONOFF_L1_ALLOW_REMOTE_INTERRUPT // During schemes 2..4 //#define SONOFF_L1_ALLOW_REMOTE_INTERRUPT // During schemes 2..4
#define SONOFF_L1_DEBUG1 // Add send and receive logging #define SONOFF_L1_DEBUG1 // Add send and receive logging
#define SONOFF_L1_BUFFER_SIZE 140 #define SONOFF_L1_BUFFER_SIZE 170
#define SONOFF_L1_MODE_COLORFUL 1 // [Color key] Colorful (static color) #define SONOFF_L1_MODE_COLORFUL 1 // [Color key] Colorful (static color)
#define SONOFF_L1_MODE_COLORFUL_GRADIENT 2 // [SMOOTH] Colorful Gradient #define SONOFF_L1_MODE_COLORFUL_GRADIENT 2 // [SMOOTH] Colorful Gradient
@ -45,18 +45,26 @@
#define SONOFF_L1_MODE_SYNC_TO_MUSIC 12 // Sync to music [Speed 1- 100, sensitivity 1 - 10] #define SONOFF_L1_MODE_SYNC_TO_MUSIC 12 // Sync to music [Speed 1- 100, sensitivity 1 - 10]
struct SNFL1 { struct SNFL1 {
char *buffer;
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT #ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
uint32_t unlock = 0; uint32_t unlock = 0;
bool receive_ready = true; bool receive_ready = true;
#endif
#ifdef SONOFF_L1_START_DELAY
char buffer[SONOFF_L1_BUFFER_SIZE];
#endif #endif
uint8_t color[3]; uint8_t color[3];
uint8_t dimmer; uint8_t dimmer;
uint8_t power; uint8_t power;
uint8_t old_music_sync = 0;
uint8_t music_sync = 0;
uint8_t sensitive;
uint8_t speed;
} Snfl1; } Snfl1;
const char kL1Commands[] PROGMEM = "L1|" // Prefix
"MusicSync";
void (* const L1Command[])(void) PROGMEM = {
&CmndMusicSync };
/********************************************************************************************/ /********************************************************************************************/
#ifdef SONOFF_L1_START_DELAY #ifdef SONOFF_L1_START_DELAY
@ -66,45 +74,24 @@ Ticker SnfL1StartDelay;
void SnfL1SendDelayed(void) { void SnfL1SendDelayed(void) {
SnfL1Send(); SnfL1Send();
} }
#endif // SONOFF_L1_START_DELAY
void SnfL1Send(void) void SnfL1Send(void) {
{
#ifdef SONOFF_L1_DEBUG1 #ifdef SONOFF_L1_DEBUG1
AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: Send %s"), Snfl1.buffer); AddLog_P(LOG_LEVEL_DEBUG, PSTR("SL1: Send %s"), Snfl1.buffer);
#endif #endif
Serial.print(Snfl1.buffer); Serial.print(Snfl1.buffer);
Serial.write(0x1B); Serial.write(0x1B);
Serial.flush(); Serial.flush();
} }
void SnfL1SerialSendOk(void) void SnfL1SerialSendOk(void) {
{ snprintf_P(Snfl1.buffer, SONOFF_L1_BUFFER_SIZE, PSTR("AT+SEND=ok"));
snprintf_P(Snfl1.buffer, sizeof(Snfl1.buffer), PSTR("AT+SEND=ok"));
SnfL1Send(); SnfL1Send();
} }
#else
void SnfL1Send(const char *buffer)
{
#ifdef SONOFF_L1_DEBUG1
AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: Send %s"), buffer);
#endif
Serial.print(buffer);
Serial.write(0x1B);
Serial.flush();
}
void SnfL1SerialSendOk(void) bool SnfL1SerialInput(void) {
{
char buffer[16];
snprintf_P(buffer, sizeof(buffer), PSTR("AT+SEND=ok"));
SnfL1Send(buffer);
}
#endif // SONOFF_L1_START_DELAY
bool SnfL1SerialInput(void)
{
if (TasmotaGlobal.serial_in_byte != 0x1B) { if (TasmotaGlobal.serial_in_byte != 0x1B) {
if (TasmotaGlobal.serial_in_byte_counter >= SONOFF_L1_BUFFER_SIZE) { if (TasmotaGlobal.serial_in_byte_counter >= SONOFF_L1_BUFFER_SIZE) {
TasmotaGlobal.serial_in_byte_counter = 0; TasmotaGlobal.serial_in_byte_counter = 0;
@ -119,7 +106,7 @@ bool SnfL1SerialInput(void)
// AT+UPDATE="sequence":"34906","switch":"on","light_type":1,"colorR":0,"colorG":16,"colorB":0,"bright":6,"mode":1 // AT+UPDATE="sequence":"34906","switch":"on","light_type":1,"colorR":0,"colorG":16,"colorB":0,"bright":6,"mode":1
// AT+UPDATE="switch":"on","light_type":1,"colorR":255,"colorG":0,"colorB":0,"bright":6,"mode":1,"speed":100,"sensitive":10 // AT+UPDATE="switch":"on","light_type":1,"colorR":255,"colorG":0,"colorB":0,"bright":6,"mode":1,"speed":100,"sensitive":10
#ifdef SONOFF_L1_DEBUG1 #ifdef SONOFF_L1_DEBUG1
AddLog(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd %s"), TasmotaGlobal.serial_in_buffer); AddLog_P(LOG_LEVEL_DEBUG, PSTR("SL1: Rcvd %s"), TasmotaGlobal.serial_in_buffer);
#endif #endif
if (!strncmp(TasmotaGlobal.serial_in_buffer +3, "RESULT", 6)) { if (!strncmp(TasmotaGlobal.serial_in_buffer +3, "RESULT", 6)) {
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT #ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
@ -240,8 +227,7 @@ bool SnfL1SerialInput(void)
/********************************************************************************************/ /********************************************************************************************/
bool SnfL1SetChannels(void) bool SnfL1SetChannels(void) {
{
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT #ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
if (Snfl1.receive_ready || TimeReached(Snfl1.unlock)) { if (Snfl1.receive_ready || TimeReached(Snfl1.unlock)) {
#endif #endif
@ -263,34 +249,30 @@ bool SnfL1SetChannels(void)
Snfl1.color[i] = scale_col[i]; Snfl1.color[i] = scale_col[i];
} }
} }
if (!power_changed && !dimmer_changed && !color_changed) { return true; } if (!power_changed && !dimmer_changed && !color_changed && (Snfl1.old_music_sync == Snfl1.music_sync)) { return true; }
#ifdef SONOFF_L1_START_DELAY uint32_t mode = SONOFF_L1_MODE_COLORFUL;
snprintf_P(Snfl1.buffer, sizeof(Snfl1.buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"light_type\":1,\"colorR\":%d,\"colorG\":%d,\"colorB\":%d,\"bright\":%d,\"mode\":%d"), if (Snfl1.music_sync) {
mode = SONOFF_L1_MODE_SYNC_TO_MUSIC;
}
snprintf_P(Snfl1.buffer, SONOFF_L1_BUFFER_SIZE, PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"light_type\":1,\"colorR\":%d,\"colorG\":%d,\"colorB\":%d,\"bright\":%d,\"mode\":%d,\"sensitive\":%d,\"speed\":%d"),
LocalTime(), millis()%1000, LocalTime(), millis()%1000,
Snfl1.power ? "on" : "off", Snfl1.power ? "on" : "off",
Snfl1.color[0], Snfl1.color[1], Snfl1.color[2], Snfl1.color[0], Snfl1.color[1], Snfl1.color[2],
Snfl1.dimmer, Snfl1.dimmer,
SONOFF_L1_MODE_COLORFUL); mode,
Snfl1.sensitive,
Snfl1.speed);
#ifdef SONOFF_L1_START_DELAY
static bool first_call = true; static bool first_call = true;
if (first_call) { if (first_call) {
SnfL1StartDelay.once_ms(900, SnfL1SendDelayed); // Allow startup time for Nuvotron microcontroller SnfL1StartDelay.once_ms(900, SnfL1SendDelayed); // Allow startup time for Nuvotron microcontroller
first_call = false; first_call = false;
} else { } else
SnfL1Send();
}
#else
char buffer[SONOFF_L1_BUFFER_SIZE];
snprintf_P(buffer, sizeof(buffer), PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"light_type\":1,\"colorR\":%d,\"colorG\":%d,\"colorB\":%d,\"bright\":%d,\"mode\":%d"),
LocalTime(), millis()%1000,
Snfl1.power ? "on" : "off",
Snfl1.color[0], Snfl1.color[1], Snfl1.color[2],
Snfl1.dimmer,
SONOFF_L1_MODE_COLORFUL);
SnfL1Send(buffer);
#endif // SONOFF_L1_START_DELAY #endif // SONOFF_L1_START_DELAY
SnfL1Send();
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT #ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
Snfl1.unlock = millis() + 500; // Allow time for the RC Snfl1.unlock = millis() + 500; // Allow time for the RC
@ -300,14 +282,18 @@ bool SnfL1SetChannels(void)
return true; return true;
} }
bool SnfL1ModuleSelected(void) bool SnfL1ModuleSelected(void) {
{
if (SONOFF_L1 == TasmotaGlobal.module_type) { if (SONOFF_L1 == TasmotaGlobal.module_type) {
if (PinUsed(GPIO_RXD) && PinUsed(GPIO_TXD)) { if (PinUsed(GPIO_RXD) && PinUsed(GPIO_TXD)) {
Snfl1.buffer = (char*)malloc(SONOFF_L1_BUFFER_SIZE);
if (Snfl1.buffer) {
SetSerial(19200, TS_SERIAL_8N1); SetSerial(19200, TS_SERIAL_8N1);
Snfl1.power = !Light.power; Snfl1.power = !Light.power;
Snfl1.dimmer = !light_state.getDimmer(); Snfl1.dimmer = !light_state.getDimmer();
Snfl1.music_sync = 0;
Snfl1.sensitive = 5; // 1..10
Snfl1.speed = 50; // 1..100
TasmotaGlobal.light_type = LT_RGB; TasmotaGlobal.light_type = LT_RGB;
TasmotaGlobal.light_driver = XLGT_05; TasmotaGlobal.light_driver = XLGT_05;
@ -315,9 +301,34 @@ bool SnfL1ModuleSelected(void)
return true; return true;
} }
} }
}
return false; return false;
} }
void CmndMusicSync(void) {
// Format is L1MusicSync on/off/toggle, sensitivity, speed
// sensitivity 1..10, speed 1..100
if (XdrvMailbox.data_len > 0) {
Snfl1.old_music_sync = Snfl1.music_sync;
uint32_t parm[3] = { 0 };
ParseParameters(3, parm);
if (2 == parm[0]) {
Snfl1.music_sync ^= 1; // Toggle
} else {
Snfl1.music_sync = parm[0] & 1; // On or Off
}
if ((parm[1] > 0) && (parm[1] < 11)) {
Snfl1.sensitive = parm[1]; // 1..10
}
if ((parm[2] > 0) && (parm[2] < 101)) {
Snfl1.speed = parm[2]; // 1..100
}
SnfL1SetChannels();
}
Response_P(PSTR("{\"%s\":{\"Mode\":\"%s\",\"Sensitive\":%d,\"Speed\":%d}}"),
XdrvMailbox.command, GetStateText(Snfl1.music_sync), Snfl1.sensitive, Snfl1.speed);
}
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
@ -336,6 +347,9 @@ bool Xlgt05(uint8_t function)
case FUNC_MODULE_INIT: case FUNC_MODULE_INIT:
result = SnfL1ModuleSelected(); result = SnfL1ModuleSelected();
break; break;
case FUNC_COMMAND:
result = DecodeCommand(kL1Commands, L1Command);
break;
} }
return result; return result;
} }

View File

@ -98,7 +98,7 @@ bool PmsReadData(void)
PmsSerial->read(); PmsSerial->read();
} }
#ifdef PMS_MODEL_PMS3003 #ifdef PMS_MODEL_PMS3003
if (PmsSerial->available() < 22) { if (PmsSerial->available() < 24) {
#else #else
if (PmsSerial->available() < 32) { if (PmsSerial->available() < 32) {
#endif // PMS_MODEL_PMS3003 #endif // PMS_MODEL_PMS3003
@ -106,8 +106,8 @@ bool PmsReadData(void)
} }
#ifdef PMS_MODEL_PMS3003 #ifdef PMS_MODEL_PMS3003
uint8_t buffer[22]; uint8_t buffer[24];
PmsSerial->readBytes(buffer, 22); PmsSerial->readBytes(buffer, 24);
#else #else
uint8_t buffer[32]; uint8_t buffer[32];
PmsSerial->readBytes(buffer, 32); PmsSerial->readBytes(buffer, 32);
@ -116,14 +116,14 @@ bool PmsReadData(void)
PmsSerial->flush(); // Make room for another burst PmsSerial->flush(); // Make room for another burst
#ifdef PMS_MODEL_PMS3003 #ifdef PMS_MODEL_PMS3003
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 22); AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 24);
#else #else
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 32); AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 32);
#endif // PMS_MODEL_PMS3003 #endif // PMS_MODEL_PMS3003
// get checksum ready // get checksum ready
#ifdef PMS_MODEL_PMS3003 #ifdef PMS_MODEL_PMS3003
for (uint32_t i = 0; i < 20; i++) { for (uint32_t i = 0; i < 22; i++) {
#else #else
for (uint32_t i = 0; i < 30; i++) { for (uint32_t i = 0; i < 30; i++) {
#endif // PMS_MODEL_PMS3003 #endif // PMS_MODEL_PMS3003
@ -131,8 +131,8 @@ bool PmsReadData(void)
} }
// The data comes in endian'd, this solves it so it works on all platforms // The data comes in endian'd, this solves it so it works on all platforms
#ifdef PMS_MODEL_PMS3003 #ifdef PMS_MODEL_PMS3003
uint16_t buffer_u16[10]; uint16_t buffer_u16[12];
for (uint32_t i = 0; i < 10; i++) { for (uint32_t i = 0; i < 12; i++) {
#else #else
uint16_t buffer_u16[15]; uint16_t buffer_u16[15];
for (uint32_t i = 0; i < 15; i++) { for (uint32_t i = 0; i < 15; i++) {
@ -141,7 +141,7 @@ bool PmsReadData(void)
buffer_u16[i] += (buffer[2 + i*2] << 8); buffer_u16[i] += (buffer[2 + i*2] << 8);
} }
#ifdef PMS_MODEL_PMS3003 #ifdef PMS_MODEL_PMS3003
if (sum != buffer_u16[9]) { if (sum != buffer_u16[10]) {
#else #else
if (sum != buffer_u16[14]) { if (sum != buffer_u16[14]) {
#endif // PMS_MODEL_PMS3003 #endif // PMS_MODEL_PMS3003
@ -150,7 +150,7 @@ bool PmsReadData(void)
} }
#ifdef PMS_MODEL_PMS3003 #ifdef PMS_MODEL_PMS3003
memcpy((void *)&pms_data, (void *)buffer_u16, 20); memcpy((void *)&pms_data, (void *)buffer_u16, 22);
#else #else
memcpy((void *)&pms_data, (void *)buffer_u16, 30); memcpy((void *)&pms_data, (void *)buffer_u16, 30);
#endif // PMS_MODEL_PMS3003 #endif // PMS_MODEL_PMS3003

View File

@ -1,5 +1,9 @@
/* /*
xsns_52_ibeacon.ino - Support for HM17 BLE Module + ibeacon reader on Tasmota xsns_52_esp32_ibeacon_ble.ino
if (!USE_IBEACON_ESP32 && USE_BLE_ESP32)
- Support for HM17 BLE Module + ibeacon reader on Tasmota (untested?)
if (USE_IBEACON_ESP32 && USE_BLE_ESP32)
- Support for BLE_ESP32 ibeacon reader on Tasmota
Copyright (C) 2020 Gerhard Mutz and Theo Arends Copyright (C) 2020 Gerhard Mutz and Theo Arends

View File

@ -1,5 +1,7 @@
/* /*
xsns_62_MI_ESP32.ino - MI-BLE-sensors via ESP32 support for Tasmota xsns_62_esp32_mi.ino - MI-BLE-sensors via ESP32 support for Tasmota
enabled by ESP32 && !USE_BLE_ESP32
if (ESP32 && USE_BLE_ESP32) then xsns_62_esp32_mi_ble.ino is used
Copyright (C) 2021 Christian Baars and Theo Arends Copyright (C) 2021 Christian Baars and Theo Arends

View File

@ -1,5 +1,8 @@
/* /*
xsns_62_MI_ESP32.ino - MI-BLE-sensors via ESP32 support for Tasmota xsns_62_esp32_mi_ble.ino - MI-BLE-sensors via ESP32 support for Tasmota
enabled by ESP32 && USE_BLE_ESP32
if (ESP32 && !USE_BLE_ESP32) then xsns_62_esp32_mi.ino is used - the older driver
Copyright (C) 2020 Christian Baars and Theo Arends Copyright (C) 2020 Christian Baars and Theo Arends
@ -20,6 +23,8 @@
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
Version yyyymmdd Action Description Version yyyymmdd Action Description
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
0.9.2.0 20210127 changed - Officially includes as the mi driver when using USE_BLE_ESP32.
-------
0.9.1.9 20201226 changed - All change now. 0.9.1.9 20201226 changed - All change now.
------- -------
0.9.1.7 20201116 changed - small bugfixes, add BLOCK and OPTION command, send BLE scan via MQTT 0.9.1.7 20201116 changed - small bugfixes, add BLOCK and OPTION command, send BLE scan via MQTT
@ -2233,7 +2238,7 @@ void CmndMi32Keys(void){
* Presentation * Presentation
\*********************************************************************************************/ \*********************************************************************************************/
const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0918{m}%u%s / %u{e}"; const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0920{m}%u%s / %u{e}";
const char HTTP_MI32_ALIAS[] PROGMEM = "{s}%s Alias {m}%s{e}"; const char HTTP_MI32_ALIAS[] PROGMEM = "{s}%s Alias {m}%s{e}";
const char HTTP_MI32_MAC[] PROGMEM = "{s}%s %s{m}%s{e}"; const char HTTP_MI32_MAC[] PROGMEM = "{s}%s %s{m}%s{e}";
const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}"; const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}";