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]
### Added
- 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
- 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
- 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)
- 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)
- Rule trigger string comparisons for EndsWith ``$>``, StartsWith ``$<`` and Contains ``$|`` (#10538)
- 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
### 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 ``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)

View File

@ -59,13 +59,19 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
## Changelog v9.2.0.4
### Added
- 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 ``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 ``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 ``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)
- 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)
- 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)
@ -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 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 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 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)
- Basic support for ESP32 M5stack core2 16MB binary tasmota32-core2.bin [#10635](https://github.com/arendst/Tasmota/issues/10635)
- Support trailing silence in buzzer tune [#10694](https://github.com/arendst/Tasmota/issues/10694)
- 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)
- 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"
#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_MQTTHOST "MqttHost"
#define D_CMND_MQTTPORT "MqttPort"
@ -375,7 +379,7 @@
#define D_CMND_SENSORRETAIN "SensorRetain"
#define D_CMND_PUBLISH "Publish"
// Commands xdrv_02_webserver.ino
// Commands xdrv_01_webserver.ino
#define D_CMND_WEBSERVER "Webserver"
#define D_JSON_WEBSERVER_MODE "WebServerMode"
#define D_JSON_ACTIVE_FOR "Active for"
@ -535,6 +539,10 @@
#define D_SO_ZIGBEE_ENDPOINTSUFFIX "EndpointSuffix"
#define D_SO_ZIGBEE_NOAUTOBIND "NoAutoBind"
#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_CMND_ZIGBEE_PERMITJOIN "PermitJoin"
#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_SVALUE[] PROGMEM = "{\"%s%d\":\"%s\"}";
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_SVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":\"%s\"}";

View File

@ -849,6 +849,10 @@
#ifdef ESP32
//#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
#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
@ -856,10 +860,6 @@
// wESP32-PoE
// #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_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 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 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 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 spare08 : 1; // bit 8
uint32_t spare09 : 1; // bit 9

View File

@ -1219,29 +1219,15 @@ int ResponseAppendTime(void)
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)
{
float dewpoint = CalcTempHumToDew(f_temperature, f_humidity);
return ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%*_f,\"" D_JSON_HUMIDITY "\":%*_f,\"" D_JSON_DEWPOINT "\":%*_f"),
Settings.flag2.temperature_resolution, &f_temperature,
Settings.flag2.humidity_resolution, &f_humidity,
Settings.flag2.temperature_resolution, &dewpoint);
}
int ResponseJsonEnd(void)
{
return ResponseAppend_P(PSTR("}"));

View File

@ -505,21 +505,12 @@ void CmndStatus(void)
}
if ((0 == payload) || (5 == payload)) {
/*
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\",\""
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_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}}"),
NetworkHostname(), NetworkAddress().toString().c_str(),
NetworkHostname(), (uint32_t)NetworkAddress(),
Settings.ipv4_address[1], Settings.ipv4_address[2], Settings.ipv4_address[3],
NetworkMacAddress().c_str(), Settings.webserver, Settings.sta_config, WifiGetOutputPower().c_str());
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS "5"));
}
@ -1517,23 +1508,20 @@ void CmndLogport(void)
void CmndIpAddress(void)
{
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) {
char stemp1[TOPSZ];
snprintf_P(stemp1, sizeof(stemp1), PSTR(" %s"), NetworkAddress().toString().c_str());
ResponseClear();
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();
} else {
uint32_t ipv4_address;
if (ParseIPv4(&ipv4_address, XdrvMailbox.data)) {
Settings.ipv4_address[XdrvMailbox.index -1] = ipv4_address;
// TasmotaGlobal.restart_flag = 2;
}
char stemp1[TOPSZ];
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:"");
Response_P(PSTR("{\"%s%d\":\"%_I%s\"}"), XdrvMailbox.command, XdrvMailbox.index, Settings.ipv4_address[XdrvMailbox.index -1], (1 == XdrvMailbox.index)?network_address:"");
}
}
}

View File

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

View File

@ -748,7 +748,7 @@ uint32_t WifiGetNtp(void) {
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;
@ -798,7 +798,7 @@ uint32_t WifiGetNtp(void) {
if ((packet_buffer[0] & 0b11000000) == 0b11000000) {
// Leap-Indicator: unknown (clock unsynchronized)
// 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
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_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_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_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)
@ -233,6 +236,7 @@
#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_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_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_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_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)
@ -416,6 +421,7 @@
#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_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_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)
@ -544,6 +550,7 @@
#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_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_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)
@ -681,6 +688,7 @@
#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_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_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)
@ -820,6 +828,7 @@
#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_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_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)

View File

@ -472,6 +472,43 @@ bool first_device_group_is_local = true;
#define DEBUG_TRACE_LOG(...)
#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_

View File

@ -2350,22 +2350,6 @@ enum SupportedModules {
M5STACK_CORE2,
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
const uint8_t kModuleNiceList[] PROGMEM = {
WEMOS,
@ -2375,16 +2359,43 @@ const uint8_t kModuleNiceList[] PROGMEM = {
#ifdef USE_ODROID_GO
ODROID_GO,
#endif // USE_ODROID_GO
// ESP32_SOLO,
// WT32_ETH01,
// TTGO_WATCH,
#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 =
{
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)
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
@ -2428,6 +2439,7 @@ const mytmplt kModules[] PROGMEM =
AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
0 // Flag
},
#ifdef USE_WEBCAM
{ // ESP32_CAM_AITHINKER - Any ESP32 device with webcam (ESP32)
AGPIO(GPIO_WEBCAM_XCLK), // 0 (I)O GPIO0, CAM_XCLK
@ -2473,6 +2485,7 @@ const mytmplt kModules[] PROGMEM =
0 // Flag
},
#endif // USE_WEBCAM
#ifdef USE_ODROID_GO
{ // ODROID_GO - (ESP32)
AGPIO(GPIO_KEY1), // 0 (I)O GPIO0, BTN-VOLUME
@ -2518,6 +2531,63 @@ const mytmplt kModules[] PROGMEM =
0 // Flag
},
#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
{ // M5STACK CORE2 - (ESP32)
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)) {
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());
}
}
@ -736,10 +736,10 @@ void WSContentSendStyle_P(const char* formatP, ...)
}
WSContentSend_P(HTTP_HEAD_STYLE3, WebColor(COL_TEXT),
#ifdef FIRMWARE_MINIMAL
WebColor(COL_TEXT_WARNING),
WebColor(COL_TEXT_WARNING),
#endif
WebColor(COL_TITLE),
ModuleName().c_str(), SettingsText(SET_DEVICENAME));
WebColor(COL_TITLE),
ModuleName().c_str(), SettingsText(SET_DEVICENAME));
if (Settings.flag3.gui_hostname_ip) { // SetOption53 - Show hostanme and IP address in GUI main menu
bool lip = (static_cast<uint32_t>(WiFi.localIP()) != 0);
bool sip = (static_cast<uint32_t>(WiFi.softAPIP()) != 0);
@ -2092,7 +2092,7 @@ void HandleInformation(void)
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_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/>"));
}
#endif
@ -2109,7 +2109,7 @@ void HandleInformation(void)
#endif
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_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/>"));
}
}
@ -2121,8 +2121,8 @@ void HandleInformation(void)
if ((WiFi.getMode() >= WIFI_AP) && (static_cast<uint32_t>(WiFi.softAPIP()) != 0)) {
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_IP_ADDRESS " (AP)}2%s"), WiFi.softAPIP().toString().c_str());
WSContentSend_P(PSTR("}1" D_GATEWAY "}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%_I"), (uint32_t)WiFi.softAPIP());
}
WSContentSend_P(PSTR("}1}2&nbsp;")); // Empty line
if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
@ -2975,8 +2975,8 @@ void CmndWebServer(void)
Settings.webserver = XdrvMailbox.payload;
}
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\"}"),
(2 == Settings.webserver) ? PSTR(D_ADMIN) : PSTR(D_USER), NetworkHostname(), NetworkAddress().toString().c_str());
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(), (uint32_t)NetworkAddress());
} else {
ResponseCmndStateText(0);
}

View File

@ -32,6 +32,13 @@
WiFiClient EspClient; // Wifi Client - non-TLS
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)
D_CMND_MQTTFINGERPRINT "|"
#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_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 = {
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
&CmndMqttFingerprint,
@ -1353,7 +1373,7 @@ bool Xdrv02(uint8_t function)
break;
#endif // USE_WEBSERVER
case FUNC_COMMAND:
result = DecodeCommand(kMqttCommands, MqttCommand);
result = DecodeCommand(kMqttCommands, MqttCommand, kMqttSynonyms);
break;
}
}

View File

@ -225,9 +225,7 @@ void EnergyUpdateToday(void)
void EnergyUpdateTotal(float value, bool kwh)
{
// char energy_total_chr[FLOATSZ];
// dtostrfd(value, 4, energy_total_chr);
// AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total %s %sWh"), energy_total_chr, (kwh) ? "k" : "");
// AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total %4_f %sWh"), &value, (kwh) ? "k" : "");
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)) {
Energy.max_energy_state = 2;
char stemp[FLOATSZ];
dtostrfd(Energy.daily, 3, stemp);
ResponseTime_P(PSTR(",\"" D_JSON_MAXENERGYREACHED "\":%s}"), stemp);
ResponseTime_P(PSTR(",\"" D_JSON_MAXENERGYREACHED "\":%3_f}"), &Energy.daily);
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
EnergyMqttShow();
SetAllPower(POWER_ALL_OFF, SRC_MAXENERGY);
@ -507,9 +503,7 @@ void EnergyEverySecond(void)
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
char temperature[33];
dtostrfd(TasmotaGlobal.temperature_celsius, 1, temperature);
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %s"), temperature);
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %1_f"), &TasmotaGlobal.temperature_celsius);
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;
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];
dtostrfd(Energy.total, Settings.flag2.energy_resolution, energy_total_chr);
char energy_daily_chr[FLOATSZ];
dtostrfd(Energy.daily, Settings.flag2.energy_resolution, energy_daily_chr);
char energy_yesterday_chr[FLOATSZ];
dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr);
char energy_usage1_chr[FLOATSZ];
dtostrfd((float)Settings.energy_usage.usage1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_usage1_chr);
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);
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]}}"),
XdrvMailbox.command,
Settings.flag2.energy_resolution, &Energy.total,
Settings.flag2.energy_resolution, &energy_kWhyesterday,
Settings.flag2.energy_resolution, &Energy.daily,
Settings.flag2.energy_resolution, &usage1_kWhtotal,
Settings.flag2.energy_resolution, &usage2_kWhtotal,
Settings.flag2.energy_resolution, &return1_kWhtotal,
Settings.flag2.energy_resolution, &return2_kWhtotal);
}
void CmndTariff(void)

View File

@ -148,11 +148,10 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
#endif // USE_DGR_LIGHT_SEQUENCE
"|UNDOCA" ;
const uint8_t kLightSynonyms[] PROGMEM = {
7, // number of entries
SO_SYNONYMS(kLightSynonyms,
37, 68, 82, 91, 92,
105, 106,
};
);
void (* const LightCommand[])(void) PROGMEM = {
&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_duration = 0; // duration of fade in milliseconds
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_max = 1023; // maxumum value for PWM, from DimmerRange, 0..1023
@ -1608,6 +1611,16 @@ void LightSetPower(void)
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
// and Light.last_color[5] the color currently displayed
// 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]];
}
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
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
LightSetOutputs(cur_col_10);
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
if (Light.fade_running) {
// 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_duration = 0; // set the value to zero to force a recompute
Light.fade_start = 0;
Light.fade_once_enabled = false; // fade will be applied, reset fade_once_enabled
// 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
// Note: Settings.light_speed is the number of half-seconds for a 100% fade,
// 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) {
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
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
#ifdef USE_LIGHT
if (!Settings.light_fade) { Light.fade_running = false; }
#endif // USE_LIGHT
ResponseCmndStateText(Settings.light_fade);
}
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 40 - Very slow
// 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);
packet_buffer[len] = 0;
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;
if (!strncmp(lp,"=>", 2)) {
lp += 2;

View File

@ -181,7 +181,7 @@ int hass_tele_period = 0;
// NEW DISCOVERY
const char HASS_DISCOVER_DEVICE[] PROGMEM = // Basic parameters for Discovery
"{\"ip\":\"%s\"," // IP Address
"{\"ip\":\"%_I\"," // IP Address
"\"dn\":\"%s\"," // Device Name
"\"fn\":[%s]," // Friendly Names
"\"hn\":\"%s\"," // Host Name
@ -336,7 +336,7 @@ void NewHAssDiscovery(void)
// Send empty message if new discovery is disabled
TasmotaGlobal.masterlog_level = 4; // Hide topic on clean and remove use weblog 4 to show it
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),
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,
@ -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\","
"\"" 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}"),
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);
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE));
}

View File

@ -1045,7 +1045,7 @@ void DisplayLogBufferInit(void)
DisplayLogBufferAdd(buffer);
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), NetworkMacAddress().c_str());
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);
if (!TasmotaGlobal.global_state.wifi_down) {
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 {
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];
if (Settings.flag5.zb_received_as_subtopic)
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 kResettingDevice[] PROGMEM = D_LOG_ZIGBEE "Resetting 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 kAbort[] PROGMEM = "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
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_OKE, Z_SRSP | Z_SYS, SYS_OSAL_NV_WRITE ) // 6109xx - NV Write, OK or error
// Factory reset
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
//ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "starting zigbee 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_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo
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_WAIT_RECV(1000, ZBR_W_OK)
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_WAIT_RECV(1000, ZBR_W_OK)
// 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
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)
// 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));
if ((0x02 == major_rel) && (0x06 == minor_rel)) {
return 0; // version 2.6.x is ok
if ((0x02 == major_rel) && ((0x06 == minor_rel) || (0x07 == minor_rel))) {
return 0; // version 2.6.x and 2.7.x are ok
} else {
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));
if ((0x02 == major_rel) && (0x06 == minor_rel)) {
return 0; // version 2.6.x is ok
if ((0x02 == major_rel) && ((0x06 == minor_rel) || (0x07 == minor_rel))) {
return 0; // version 2.6.x and 2.7.x are ok
} else {
return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort
}

View File

@ -26,7 +26,7 @@
const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
// 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_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
D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|"
#endif // USE_ZIGBEE_ZNP
@ -42,11 +42,10 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA
;
const uint8_t kZbSynonyms[] PROGMEM = {
6, // number of synonyms
SO_SYNONYMS(kZbSynonyms,
83, 89, 100, 101, 110,
112,
};
112, 120, 116, 118, 119,
);
void (* const ZigbeeCommand[])(void) PROGMEM = {
#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 count = 0; // Number of buzzes
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 duration;
uint8_t state = 0;
uint8_t tune_size = 0;
uint8_t size = 0;
} Buzzer;
/*********************************************************************************************/
void BuzzerSet(uint8_t state)
{
void BuzzerSet(uint32_t state) {
if (Buzzer.inverted) {
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;
if (last_state != state) {
if (state) {
analogWrite(Pin(GPIO_BUZZER, 0), Settings.pwm_range / 2); // set 50% 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
}
// 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
last_state = state;
}
} else {
DigitalWrite(GPIO_BUZZER, 0, state); // Buzzer On/Off
}
else {
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, uint32_t on, uint32_t off, uint32_t tune, uint32_t mode)
{
Buzzer.set[0] = off; // off duration in 100 mSec steps
Buzzer.set[1] = on; // on duration in 100 mSec steps
Buzzer.duration = 1; // Start buzzer on first step
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[1] = on; // On duration in 100 mSec steps
Buzzer.duration = 1; // Start buzzer on first step
Buzzer.size = 0;
Buzzer.tune_size = 0;
Buzzer.tune = 0;
Buzzer.tune_reload = 0;
Buzzer.mode = mode;
@ -78,65 +75,55 @@ void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32
uint32_t tune2 = tune;
for (uint32_t i = 0; i < 32; i++) {
if (!(tune2 & 0x80000000)) {
tune2 <<= 1; // Skip leading silence
tune2 <<= 1; // Skip leading silence
} else {
Buzzer.tune_reload <<= 1; // Add swapped tune
Buzzer.tune_size++; // Allow trailing silence
Buzzer.tune_reload <<= 1; // Add swapped tune
Buzzer.tune_reload |= tune1 & 1;
tune1 >>= 1;
}
}
Buzzer.size = Buzzer.tune_size;
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.
if (Settings.flag4.buzzer_freq_mode) { // SetOption111 - Enable frequency output mode for buzzer
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);
AddLog(LOG_LEVEL_DEBUG, PSTR("BUZ: Count %d(%d), Time %d/%d, Tune 0x%08X(0x%08X), Size %d, Mode %d"),
count, Buzzer.count, on, off, tune, Buzzer.tune, Buzzer.tune_size, Settings.flag4.buzzer_freq_mode);
Buzzer.enable = (Buzzer.count > 0);
if (Buzzer.enable) {
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 {
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 {
TasmotaGlobal.sleep = Settings.sleep; // restore original sleep
} else {
TasmotaGlobal.sleep = Settings.sleep; // Restore original sleep
BuzzerSet(0);
}
}
void BuzzerSetStateToLed(uint32_t state)
{
void BuzzerSetStateToLed(uint32_t state) {
if (Buzzer.enable && (2 == Buzzer.mode)) {
Buzzer.state = (state != 0);
BuzzerSet(Buzzer.state);
}
}
void BuzzerBeep(uint32_t count)
{
void BuzzerBeep(uint32_t count) {
BuzzerBeep(count, 1, 1, 0, 0);
}
void BuzzerEnabledBeep(uint32_t count, uint32_t duration)
{
if (Settings.flag3.buzzer_enable) { // SetOption67 - Enable buzzer when available
void BuzzerEnabledBeep(uint32_t count, uint32_t duration) {
if (Settings.flag3.buzzer_enable) { // SetOption67 - Enable buzzer when available
BuzzerBeep(count, duration, 1, 0, 0);
}
}
/*********************************************************************************************/
bool BuzzerPinState(void)
{
bool BuzzerPinState(void) {
if (XdrvMailbox.index == AGPIO(GPIO_BUZZER_INV)) {
Buzzer.inverted = 1;
XdrvMailbox.index -= (AGPIO(GPIO_BUZZER_INV) - AGPIO(GPIO_BUZZER));
@ -145,8 +132,7 @@ bool BuzzerPinState(void)
return false;
}
void BuzzerInit(void)
{
void BuzzerInit(void) {
if (PinUsed(GPIO_BUZZER)) {
pinMode(Pin(GPIO_BUZZER), OUTPUT);
BuzzerSet(0);
@ -155,17 +141,18 @@ void BuzzerInit(void)
}
}
void BuzzerEvery100mSec(void)
{
void BuzzerEvery100mSec(void) {
if (Buzzer.enable && (Buzzer.mode != 2)) {
if (Buzzer.count) {
if (Buzzer.duration) {
Buzzer.duration--;
if (!Buzzer.duration) {
if (Buzzer.tune) {
if (Buzzer.size) {
Buzzer.size--;
Buzzer.state = Buzzer.tune & 1;
Buzzer.tune >>= 1;
} else {
Buzzer.size = Buzzer.tune_size;
Buzzer.tune = Buzzer.tune_reload;
Buzzer.count -= (Buzzer.tune_reload) ? 2 : 1;
Buzzer.state = Buzzer.count & 1;
@ -187,25 +174,29 @@ void BuzzerEvery100mSec(void)
* Commands
\*********************************************************************************************/
const char kBuzzerCommands[] PROGMEM = "|" // No prefix
"Buzzer" ;
const char kBuzzerCommands[] PROGMEM = "Buzzer|" // Prefix
"Active|Pwm||" ;
SO_SYNONYMS(kBuzzerSynonyms,
67, 111
);
void (* const BuzzerCommand[])(void) PROGMEM = {
&CmndBuzzer };
void CmndBuzzer(void)
{
void CmndBuzzer(void) {
// Buzzer <number of beeps>,<duration of beep in 100mS steps>,<duration of silence in 100mS steps>,<tune>
// All parameters are optional
//
// Buzzer = Buzzer 1,1,1 = Beep once with both duration and pause set to 100mS
// Buzzer 0 = Stop active beep cycle
// Buzzer 2 = Beep twice with duration 200mS 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,0xF54 = Beep a sequence twice indicated by 0xF54 = 1111 0101 01 with duration 300mS and pause 400mS
// Buzzer -1 = Beep infinite
// Buzzer -2 = Beep following link led
// Buzzer = Buzzer 1,1,1 = Beep once with both duration and pause set to 100mS
// Buzzer 0 = Stop active beep cycle
// Buzzer 2 = Beep twice with duration 200mS 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,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 -2 = Beep following link led
if (XdrvMailbox.data_len > 0) {
if (XdrvMailbox.payload != 0) {
@ -213,11 +204,11 @@ void CmndBuzzer(void)
uint32_t mode = 0;
ParseParameters(4, parm);
if (XdrvMailbox.payload <= 0) {
parm[0] = 1; // Default Count
mode = -XdrvMailbox.payload; // 0, 1 or 2
parm[0] = 1; // Default Count
mode = -XdrvMailbox.payload; // 0, 1 or 2
}
for (uint32_t i = 1; i < 3; i++) {
if (parm[i] < 1) { parm[i] = 1; } // Default On time, Off time
if (parm[i] < 1) { parm[i] = 1; } // Default On time, Off time
}
BuzzerBeep(parm[0], parm[1], parm[2], parm[3], mode);
} else {
@ -233,8 +224,7 @@ void CmndBuzzer(void)
* Interface
\*********************************************************************************************/
bool Xdrv24(uint8_t function)
{
bool Xdrv24(uint8_t function) {
bool result = false;
if (Buzzer.active) {
@ -243,7 +233,7 @@ bool Xdrv24(uint8_t function)
BuzzerEvery100mSec();
break;
case FUNC_COMMAND:
result = DecodeCommand(kBuzzerCommands, BuzzerCommand);
result = DecodeCommand(kBuzzerCommands, BuzzerCommand, kBuzzerSynonyms);
break;
case FUNC_PRE_INIT:
BuzzerInit();

View File

@ -619,13 +619,13 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
if (mqtt_trigger) {
char topic[TOPSZ];
sprintf_P(TasmotaGlobal.mqtt_data, PSTR("Trigger%u"), mqtt_trigger);
#ifdef USE_PWM_DIMMER_REMOTE
if (Settings.flag4.multiple_device_groups) {
#ifdef USE_DEVICE_GROUPS
if (Settings.flag4.device_groups_enabled) {
snprintf_P(topic, sizeof(topic), PSTR("cmnd/%s/EVENT"), device_groups[power_button_index].group_name);
MqttPublish(topic);
}
else
#endif // USE_PWM_DIMMER_REMOTE
#endif // USE_DEVICE_GROUPS
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";
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 =
"</div>";
@ -436,11 +436,11 @@ const char UFS_FORM_SDC_DIRd[] PROGMEM =
const char UFS_FORM_SDC_DIRb[] PROGMEM =
"<pre><a href='%s' file='%s'>%s</a> %s %8d %s</pre>";
const char UFS_FORM_SDC_HREF[] PROGMEM =
"http://%s/ufsd?download=%s/%s";
"http://%_I/ufsd?download=%s/%s";
#ifdef GUI_TRASH_FILE
const char UFS_FORM_SDC_HREFdel[] PROGMEM =
//"<a href=http://%s/ufsd?delete=%s/%s>&#128465;</a>";
"<a href=http://%s/ufsd?delete=%s/%s>&#128293;</a>"; // 🔥
//"<a href=http://%_I/ufsd?delete=%s/%s>&#128465;</a>";
"<a href=http://%_I/ufsd?delete=%s/%s>&#128293;</a>"; // 🔥
#endif // GUI_TRASH_FILE
void UfsDirectory(void) {
@ -492,7 +492,7 @@ void UfsDirectory(void) {
WSContentSend_PD(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs);
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);
@ -520,7 +520,7 @@ void UfsListDir(char *path, uint8_t depth) {
if (dir) {
dir.rewindDirectory();
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--) {
if (npath[cnt] == '/') {
if (npath[cnt - 1] == '=') {
@ -562,7 +562,7 @@ void UfsListDir(char *path, uint8_t depth) {
sprintf(cp, format, ep);
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);
uint8_t plen = strlen(path);
if (plen > 1) {
@ -574,12 +574,12 @@ void UfsListDir(char *path, uint8_t depth) {
} else {
#ifdef GUI_TRASH_FILE
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
char delpath[2];
delpath[0]=0;
#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);
}
}

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
@ -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
BLE functionality to implement specific drivers on top of it.
@ -35,34 +45,26 @@
connect/read/awaitnotify from a MAC/Service/Characteristic/NotifyCharacteristic
Cmnds:
BLEOp0 - requests status of operations
BLEOp1 MAC - create an operation in preparation, and populate it's MAC address
BLEOp2 Service - add a serviceUUID to the operation in preparation
BLEOp3 Characteristic - add a CharacteristicUUID to the operation in preparation for read/write
BLEOp4 writedata - optional:add data to write to the operation in preparation - hex string
BLEOp5 - optional:signify that a read should be done
BLEOp6 NotifyCharacteristic - optional:add a NotifyCharacteristicUUID to the operation in preparation to wait for a notify
BLEOp9 - publish the 'operation in preparation' to MQTT.
BLEOp10 - add the 'operation in preparation' to the queue of operations to perform.
BLEPeriod
BLEAdv
BLEOp
BLEMode
BLEDetails
BLEScan
BLEAlias
BLEName
BLEDebug
BLEDevices
BLEMaxAge
BLEAddrFilter
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
Example:
Example BLEOp:
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;
BLEOp10 ->
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.)
BLEOp M:4C65A8DAF43A s:00001530-1212-efde-1523-785feabcd123 n:00001531-1212-efde-1523-785feabcd123 c:00001531-1212-efde-1523-785feabcd123 w:00 go
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"}}
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
// uncomment for more diagnostic/information messages - + more flash use.
//#define BLE_ESP32_DEBUG
#define XDRV_52 52
#define XDRV_79 79
#define USE_MI_DECRYPTION
#include <vector>
@ -3456,7 +3443,7 @@ int ExtStopBLE(){
return 0;
}
bool Xdrv52(uint8_t function)
bool Xdrv79(uint8_t function)
{
//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
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
@ -918,8 +918,8 @@ void WcShowStream(void) {
delay(50); // Give the webcam webserver some time to prepare the stream
}
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>"),
WiFi.localIP().toString().c_str());
WSContentSend_P(PSTR("<p></p><center><img src='http://%_I:81/stream' alt='Webcam stream' style='width:99%%;'></center><p></p>"),
(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
@ -93,8 +93,8 @@ void EthernetEvent(WiFiEvent_t event) {
ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "");
break;
case SYSTEM_EVENT_ETH_GOT_IP:
AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"),
ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname);
AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %_I, Hostname %s"),
ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname);
Settings.ipv4_address[1] = (uint32_t)ETH.gatewayIP();
Settings.ipv4_address[2] = (uint32_t)ETH.subnetMask();
Settings.ipv4_address[3] = (uint32_t)ETH.dnsIP();
@ -120,6 +120,12 @@ void EthernetInit(void) {
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);
strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_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

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

View File

@ -25,11 +25,11 @@
#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_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_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]
struct SNFL1 {
char *buffer;
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
uint32_t unlock = 0;
bool receive_ready = true;
#endif
#ifdef SONOFF_L1_START_DELAY
char buffer[SONOFF_L1_BUFFER_SIZE];
#endif
uint8_t color[3];
uint8_t dimmer;
uint8_t power;
uint8_t old_music_sync = 0;
uint8_t music_sync = 0;
uint8_t sensitive;
uint8_t speed;
} Snfl1;
const char kL1Commands[] PROGMEM = "L1|" // Prefix
"MusicSync";
void (* const L1Command[])(void) PROGMEM = {
&CmndMusicSync };
/********************************************************************************************/
#ifdef SONOFF_L1_START_DELAY
@ -66,45 +74,24 @@ Ticker SnfL1StartDelay;
void SnfL1SendDelayed(void) {
SnfL1Send();
}
#endif // SONOFF_L1_START_DELAY
void SnfL1Send(void)
{
void SnfL1Send(void) {
#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
Serial.print(Snfl1.buffer);
Serial.write(0x1B);
Serial.flush();
}
void SnfL1SerialSendOk(void)
{
snprintf_P(Snfl1.buffer, sizeof(Snfl1.buffer), PSTR("AT+SEND=ok"));
void SnfL1SerialSendOk(void) {
snprintf_P(Snfl1.buffer, SONOFF_L1_BUFFER_SIZE, PSTR("AT+SEND=ok"));
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)
{
char buffer[16];
snprintf_P(buffer, sizeof(buffer), PSTR("AT+SEND=ok"));
SnfL1Send(buffer);
}
#endif // SONOFF_L1_START_DELAY
bool SnfL1SerialInput(void)
{
bool SnfL1SerialInput(void) {
if (TasmotaGlobal.serial_in_byte != 0x1B) {
if (TasmotaGlobal.serial_in_byte_counter >= SONOFF_L1_BUFFER_SIZE) {
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="switch":"on","light_type":1,"colorR":255,"colorG":0,"colorB":0,"bright":6,"mode":1,"speed":100,"sensitive":10
#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
if (!strncmp(TasmotaGlobal.serial_in_buffer +3, "RESULT", 6)) {
#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
if (Snfl1.receive_ready || TimeReached(Snfl1.unlock)) {
#endif
@ -263,34 +249,30 @@ bool SnfL1SetChannels(void)
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
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"),
uint32_t mode = SONOFF_L1_MODE_COLORFUL;
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,
Snfl1.power ? "on" : "off",
Snfl1.color[0], Snfl1.color[1], Snfl1.color[2],
Snfl1.dimmer,
SONOFF_L1_MODE_COLORFUL);
mode,
Snfl1.sensitive,
Snfl1.speed);
#ifdef SONOFF_L1_START_DELAY
static bool first_call = true;
if (first_call) {
SnfL1StartDelay.once_ms(900, SnfL1SendDelayed); // Allow startup time for Nuvotron microcontroller
first_call = false;
} 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);
} else
#endif // SONOFF_L1_START_DELAY
SnfL1Send();
#ifdef SONOFF_L1_ALLOW_REMOTE_INTERRUPT
Snfl1.unlock = millis() + 500; // Allow time for the RC
@ -300,24 +282,53 @@ bool SnfL1SetChannels(void)
return true;
}
bool SnfL1ModuleSelected(void)
{
bool SnfL1ModuleSelected(void) {
if (SONOFF_L1 == TasmotaGlobal.module_type) {
if (PinUsed(GPIO_RXD) && PinUsed(GPIO_TXD)) {
SetSerial(19200, TS_SERIAL_8N1);
Snfl1.buffer = (char*)malloc(SONOFF_L1_BUFFER_SIZE);
if (Snfl1.buffer) {
SetSerial(19200, TS_SERIAL_8N1);
Snfl1.power = !Light.power;
Snfl1.dimmer = !light_state.getDimmer();
Snfl1.power = !Light.power;
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_driver = XLGT_05;
AddLog(LOG_LEVEL_DEBUG, PSTR("LGT: Sonoff L1 Found"));
return true;
TasmotaGlobal.light_type = LT_RGB;
TasmotaGlobal.light_driver = XLGT_05;
AddLog(LOG_LEVEL_DEBUG, PSTR("LGT: Sonoff L1 Found"));
return true;
}
}
}
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
\*********************************************************************************************/
@ -336,6 +347,9 @@ bool Xlgt05(uint8_t function)
case FUNC_MODULE_INIT:
result = SnfL1ModuleSelected();
break;
case FUNC_COMMAND:
result = DecodeCommand(kL1Commands, L1Command);
break;
}
return result;
}

View File

@ -98,7 +98,7 @@ bool PmsReadData(void)
PmsSerial->read();
}
#ifdef PMS_MODEL_PMS3003
if (PmsSerial->available() < 22) {
if (PmsSerial->available() < 24) {
#else
if (PmsSerial->available() < 32) {
#endif // PMS_MODEL_PMS3003
@ -106,8 +106,8 @@ bool PmsReadData(void)
}
#ifdef PMS_MODEL_PMS3003
uint8_t buffer[22];
PmsSerial->readBytes(buffer, 22);
uint8_t buffer[24];
PmsSerial->readBytes(buffer, 24);
#else
uint8_t buffer[32];
PmsSerial->readBytes(buffer, 32);
@ -116,14 +116,14 @@ bool PmsReadData(void)
PmsSerial->flush(); // Make room for another burst
#ifdef PMS_MODEL_PMS3003
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 22);
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 24);
#else
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 32);
#endif // PMS_MODEL_PMS3003
// get checksum ready
#ifdef PMS_MODEL_PMS3003
for (uint32_t i = 0; i < 20; i++) {
for (uint32_t i = 0; i < 22; i++) {
#else
for (uint32_t i = 0; i < 30; i++) {
#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
#ifdef PMS_MODEL_PMS3003
uint16_t buffer_u16[10];
for (uint32_t i = 0; i < 10; i++) {
uint16_t buffer_u16[12];
for (uint32_t i = 0; i < 12; i++) {
#else
uint16_t buffer_u16[15];
for (uint32_t i = 0; i < 15; i++) {
@ -141,7 +141,7 @@ bool PmsReadData(void)
buffer_u16[i] += (buffer[2 + i*2] << 8);
}
#ifdef PMS_MODEL_PMS3003
if (sum != buffer_u16[9]) {
if (sum != buffer_u16[10]) {
#else
if (sum != buffer_u16[14]) {
#endif // PMS_MODEL_PMS3003
@ -150,7 +150,7 @@ bool PmsReadData(void)
}
#ifdef PMS_MODEL_PMS3003
memcpy((void *)&pms_data, (void *)buffer_u16, 20);
memcpy((void *)&pms_data, (void *)buffer_u16, 22);
#else
memcpy((void *)&pms_data, (void *)buffer_u16, 30);
#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

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

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
@ -20,6 +23,8 @@
--------------------------------------------------------------------------------------------
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.7 20201116 changed - small bugfixes, add BLOCK and OPTION command, send BLE scan via MQTT
@ -2233,7 +2238,7 @@ void CmndMi32Keys(void){
* 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_MAC[] PROGMEM = "{s}%s %s{m}%s{e}";
const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}";