More sensible behaviour
* When setting PWM values, updates all the LEDs (instant response). Uses led_power values.
* If LEDLINK not set, but LED1 is, LED1 is the status led. When turning on/off, setledlink uses digitalwrite (which does not respect the new pwm operation). In this case only, we will use the setledpoweridx instead of digitalwrite - costly (every 250ms this runs), but edge case / legacy. Allows more intuitive operation - if we blink an LED with the max and min PWM limits, we'd expect it to respect these. In this case, blink will also now update the led_power status, which keeps this accurate e.g. if ledpower 1 cmnd was sent, then blink occurred, led_state would read a 1 for that bit but the led would be off (but nothing was reading it for status so it didn't cause any trouble). Leaving digitalwrite when LEDLINK is defined as this is more efficient and the use case for pwm leds is to find buttons - link indicator would become more ambiguous for no benefit.
2020-05-20 02:25:32 +01:00
/*
2019-10-27 11:04:08 +00:00
tasmota . ino - Tasmota firmware for iTead Sonoff , Wemos and NodeMCU hardware
2017-05-13 12:02:10 +01:00
2019-12-31 13:23:34 +00:00
Copyright ( C ) 2020 Theo Arends
2017-05-13 12:02:10 +01:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2017-05-17 21:49:22 +01:00
/*====================================================
2017-05-13 12:02:10 +01:00
Prerequisites :
- Change libraries / PubSubClient / src / PubSubClient . h
2020-02-12 17:00:53 +00:00
# define MQTT_MAX_PACKET_SIZE 1200
2017-07-15 14:07:30 +01:00
2020-03-02 16:48:19 +00:00
Arduino IDE 1.8 .12 and up parameters
- Select IDE Tools - Board : " Generic ESP8266 Module "
- Select IDE Tools - Flash Mode : " DOUT (compatible) "
- Select IDE Tools - Flash Size : " 1M (FS:none OTA:~502KB) "
- Select IDE Tools - LwIP Variant : " v2 Higher Bandwidth (no feature) "
- Select IDE Tools - VTables : " Flash "
- Select IDE Tools - Espressif FW : " nonos-sdk-2.2.1+100 (190703) "
2017-05-17 21:49:22 +01:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2017-01-28 13:41:01 +00:00
2017-10-18 17:22:34 +01:00
// Location specific includes
2018-01-26 14:21:57 +00:00
# include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
2020-04-10 17:24:08 +01:00
# include "tasmota_compat.h"
2019-10-27 11:04:08 +00:00
# include "tasmota_version.h" // Tasmota version information
# include "tasmota.h" // Enumeration used in my_user_config.h
2018-10-23 14:51:51 +01:00
# include "my_user_config.h" // Fixed user configurable options
2019-06-19 08:49:48 +01:00
# ifdef USE_MQTT_TLS
2020-04-10 09:52:22 +01:00
# include <t_bearssl.h> // We need to include before "tasmota_globals.h" to take precedence over the BearSSL version in Arduino
2019-06-19 08:49:48 +01:00
# endif // USE_MQTT_TLS
2020-04-09 14:32:23 +01:00
# include "tasmota_globals.h" // Function prototypes and global configuration
2018-10-23 14:51:51 +01:00
# include "i18n.h" // Language support configured by my_user_config.h
2019-10-27 11:04:08 +00:00
# include "tasmota_template.h" // Hardware configuration
2017-03-03 11:35:23 +00:00
2018-02-27 13:59:46 +00:00
# ifdef ARDUINO_ESP8266_RELEASE_2_4_0
# include "lwip/init.h"
# if LWIP_VERSION_MAJOR != 1
# error Please use stable lwIP v1.4
# endif
2017-03-03 11:35:23 +00:00
# endif
2018-01-18 15:19:28 +00:00
2018-02-27 13:59:46 +00:00
// Libraries
2018-11-20 14:00:24 +00:00
# include <ESP8266HTTPClient.h> // Ota
2017-01-28 13:41:01 +00:00
# include <ESP8266httpUpdate.h> // Ota
2017-06-04 16:40:27 +01:00
# include <StreamString.h> // Webserver, Updater
2017-02-17 16:18:41 +00:00
# include <ArduinoJson.h> // WemoHue, IRremote, Domoticz
2018-03-21 16:58:39 +00:00
# ifdef USE_ARDUINO_OTA
# include <ArduinoOTA.h> // Arduino OTA
# ifndef USE_DISCOVERY
# define USE_DISCOVERY
# endif
# endif // USE_ARDUINO_OTA
2017-01-28 13:41:01 +00:00
# ifdef USE_DISCOVERY
2018-03-21 16:58:39 +00:00
# include <ESP8266mDNS.h> // MQTT, Webserver, Arduino OTA
2017-01-28 13:41:01 +00:00
# endif // USE_DISCOVERY
# ifdef USE_I2C
# include <Wire.h> // I2C support library
# endif // USE_I2C
2017-07-15 14:07:30 +01:00
# ifdef USE_SPI
2017-05-10 13:19:36 +01:00
# include <SPI.h> // SPI support, TFT
2017-04-29 13:40:53 +01:00
# endif // USE_SPI
2019-02-17 09:42:55 +00:00
2017-10-18 17:22:34 +01:00
// Structs
2017-02-19 16:49:17 +00:00
# include "settings.h"
2017-01-28 13:41:01 +00:00
2019-12-02 09:44:27 +00:00
/*********************************************************************************************\
* Global variables
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-08-27 15:07:23 +01:00
WiFiUDP PortUdp ; // UDP Syslog and Alexa
2018-05-17 14:36:45 +01:00
unsigned long feature_drv1 ; // Compiled driver feature map
unsigned long feature_drv2 ; // Compiled driver feature map
unsigned long feature_sns1 ; // Compiled sensor feature map
unsigned long feature_sns2 ; // Compiled sensor feature map
2019-08-07 11:56:32 +01:00
unsigned long feature5 ; // Compiled feature map
2020-02-10 14:18:11 +00:00
unsigned long feature6 ; // Compiled feature map
2018-08-27 11:01:20 +01:00
unsigned long serial_polling_window = 0 ; // Serial polling window
unsigned long state_second = 0 ; // State second timer
unsigned long state_50msecond = 0 ; // State 50msecond timer
unsigned long state_100msecond = 0 ; // State 100msecond timer
unsigned long state_250msecond = 0 ; // State 250msecond timer
unsigned long pulse_timer [ MAX_PULSETIMERS ] = { 0 } ; // Power off timer
unsigned long blink_timer = 0 ; // Power cycle timer
unsigned long backlog_delay = 0 ; // Command backlog delay
power_t power = 0 ; // Current copy of Settings.power
2019-09-04 11:20:04 +01:00
power_t last_power = 0 ; // Last power set state
2018-08-27 15:07:23 +01:00
power_t blink_power ; // Blink power state
power_t blink_mask = 0 ; // Blink relay active mask
power_t blink_powersave ; // Blink start power save state
power_t latching_power = 0 ; // Power state at latching start
power_t rel_inverted = 0 ; // Relay inverted flag (1 = (0 = On, 1 = Off))
2017-10-18 17:22:34 +01:00
int serial_in_byte_counter = 0 ; // Index in receive buffer
int ota_state_flag = 0 ; // OTA state flag
int ota_result = 0 ; // OTA result
2019-10-27 11:04:08 +00:00
int restart_flag = 0 ; // Tasmota restart flag
2017-10-18 17:22:34 +01:00
int wifi_state_flag = WIFI_RESTART ; // Wifi state flag
2018-08-27 15:07:23 +01:00
int blinks = 201 ; // Number of LED blinks
uint32_t uptime = 0 ; // Counting every second until 4294967295 = 130 year
2018-11-24 16:16:27 +00:00
uint32_t loop_load_avg = 0 ; // Indicative loop load average
2018-08-27 15:07:23 +01:00
uint32_t global_update = 0 ; // Timestamp of last global temperature and humidity update
2019-10-14 15:12:59 +01:00
uint32_t web_log_index = 1 ; // Index in Web log buffer (should never be 0)
float global_temperature = 9999 ; // Provide a global temperature to be used by some sensors
2018-08-27 15:07:23 +01:00
float global_humidity = 0 ; // Provide a global humidity to be used by some sensors
2019-04-15 17:12:42 +01:00
float global_pressure = 0 ; // Provide a global pressure to be used by some sensors
2019-11-13 08:25:09 +00:00
uint16_t tele_period = 9999 ; // Tele period timer
2018-08-27 15:07:23 +01:00
uint16_t blink_counter = 0 ; // Number of blink cycles
uint16_t seriallog_timer = 0 ; // Timer to disable Seriallog
uint16_t syslog_timer = 0 ; // Timer to re-enable syslog_level
2020-04-28 17:27:07 +01:00
# ifdef ESP32
2020-04-29 13:01:02 +01:00
uint16_t gpio_pin [ MAX_GPIO_PIN ] = { 0 } ; // GPIO functions indexed by pin number
2020-04-28 17:27:07 +01:00
# endif // ESP32
2018-08-27 15:07:23 +01:00
int16_t save_data_counter ; // Counter and flag for config save to Flash
RulesBitfield rules_flag ; // Rule state flags (16 bits)
2020-01-18 15:57:48 +00:00
uint8_t mqtt_cmnd_blocked = 0 ; // Ignore flag for publish command
uint8_t mqtt_cmnd_blocked_reset = 0 ; // Count down to reset if needed
2018-08-27 15:07:23 +01:00
uint8_t state_250mS = 0 ; // State 250msecond per second flag
2017-10-18 17:22:34 +01:00
uint8_t latching_relay_pulse = 0 ; // Latching relay pulse timer
2020-04-10 17:24:08 +01:00
uint8_t ssleep ; // Current copy of Settings.sleep
2018-07-07 16:30:58 +01:00
uint8_t blinkspeed = 1 ; // LED blink rate
2020-04-28 17:27:07 +01:00
# ifdef ESP8266
2020-04-29 13:01:02 +01:00
uint8_t gpio_pin [ MAX_GPIO_PIN ] = { 0 } ; // GPIO functions indexed by pin number
2020-04-28 17:27:07 +01:00
# endif // ESP8266 - ESP32
2019-06-08 10:38:45 +01:00
uint8_t active_device = 1 ; // Active device in ExecuteCommandPower
2019-05-21 17:11:39 +01:00
uint8_t leds_present = 0 ; // Max number of LED supported
2017-10-18 17:22:34 +01:00
uint8_t led_inverted = 0 ; // LED inverted flag (1 = (0 = On, 1 = Off))
2019-05-21 17:11:39 +01:00
uint8_t led_power = 0 ; // LED power state
uint8_t ledlnk_inverted = 0 ; // Link LED inverted flag (1 = (0 = On, 1 = Off))
2017-10-18 17:22:34 +01:00
uint8_t pwm_inverted = 0 ; // PWM inverted flag (1 = inverted)
2018-09-04 15:22:34 +01:00
uint8_t energy_flg = 0 ; // Energy monitor configured
2019-10-06 16:19:05 +01:00
uint8_t light_flg = 0 ; // Light module configured
2017-10-18 17:22:34 +01:00
uint8_t light_type = 0 ; // Light types
2019-01-28 13:08:33 +00:00
uint8_t serial_in_byte ; // Received byte
uint8_t ota_retry_counter = OTA_ATTEMPTS ; // OTA retry counter
uint8_t devices_present = 0 ; // Max number of devices supported
uint8_t seriallog_level ; // Current copy of Settings.seriallog_level
uint8_t syslog_level ; // Current copy of Settings.syslog_level
2019-02-11 18:21:49 +00:00
uint8_t my_module_type ; // Current copy of Settings.module or user template type
2020-05-01 15:47:41 +01:00
uint8_t my_adc0 = 0 ; // Active copy of Module ADC0
2019-09-30 10:21:43 +01:00
uint8_t last_source = 0 ; // Last command source
2019-09-29 17:00:01 +01:00
uint8_t shutters_present = 0 ; // Number of actual define shutters
2020-01-14 11:47:48 +00:00
uint8_t prepped_loglevel = 0 ; // Delayed log level message
2019-01-28 13:08:33 +00:00
//uint8_t mdns_delayed_start = 0; // mDNS delayed start
2020-05-11 14:27:29 +01:00
bool serial_local = false ; // Handle serial locally
bool serial_buffer_overrun = false ; // Serial buffer overrun
2019-01-28 13:08:33 +00:00
bool fallback_topic_flag = false ; // Use Topic or FallbackTopic
bool backlog_mutex = false ; // Command backlog pending
bool interlock_mutex = false ; // Interlock power command pending
bool stop_flash_rotate = false ; // Allow flash configuration rotation
bool blinkstate = false ; // LED state
2019-07-06 11:53:07 +01:00
//bool latest_uptime_flag = true; // Signal latest uptime
2019-01-28 13:08:33 +00:00
bool pwm_present = false ; // Any PWM channel configured with SetOption15 0
bool i2c_flg = false ; // I2C configured
bool spi_flg = false ; // SPI configured
bool soft_spi_flg = false ; // Software SPI configured
bool ntp_force_sync = false ; // Force NTP sync
2019-12-02 09:31:33 +00:00
bool is_8285 = false ; // Hardware device ESP8266EX (0) or ESP8285 (1)
2020-03-05 23:51:22 +00:00
bool skip_light_fade ; // Temporarily skip light fading
2019-01-07 15:33:18 +00:00
myio my_module ; // Active copy of Module GPIOs (17 x 8 bits)
2019-05-13 14:56:01 +01:00
gpio_flag my_module_flag ; // Active copy of Template GPIO flags
2018-08-27 15:07:23 +01:00
StateBitfield global_state ; // Global states (currently Wifi and Mqtt) (8 bits)
2018-01-10 13:10:25 +00:00
char my_version [ 33 ] ; // Composed version string
2020-01-23 09:33:08 +00:00
char my_image [ 33 ] ; // Code image and/or commit
2017-10-18 17:22:34 +01:00
char my_hostname [ 33 ] ; // Composed Wifi hostname
2019-12-22 14:23:52 +00:00
char mqtt_client [ TOPSZ ] ; // Composed MQTT Clientname
char mqtt_topic [ TOPSZ ] ; // Composed MQTT topic
2018-02-08 11:45:26 +00:00
char serial_in_buffer [ INPUT_BUFFER_SIZE ] ; // Receive buffer
2018-01-18 15:19:28 +00:00
char mqtt_data [ MESSZ ] ; // MQTT publish buffer and web page ajax buffer
char log_data [ LOGSZ ] ; // Logging
2018-01-30 13:14:55 +00:00
char web_log [ WEB_LOG_SIZE ] = { ' \0 ' } ; // Web log buffer
2019-09-09 16:24:27 +01:00
# ifdef SUPPORT_IF_STATEMENT
# include <LinkedList.h>
2019-10-14 15:12:59 +01:00
LinkedList < String > backlog ; // Command backlog implemented with LinkedList
2019-09-09 16:24:27 +01:00
# define BACKLOG_EMPTY (backlog.size() == 0)
# else
2019-10-14 15:12:59 +01:00
uint8_t backlog_index = 0 ; // Command backlog index
uint8_t backlog_pointer = 0 ; // Command backlog pointer
String backlog [ MAX_BACKLOG ] ; // Command backlog buffer
2019-09-09 16:24:27 +01:00
# define BACKLOG_EMPTY (backlog_pointer == backlog_index)
# endif
2018-11-24 16:16:27 +00:00
2017-07-25 17:05:47 +01:00
/*********************************************************************************************\
2019-12-02 09:44:27 +00:00
* Main
2017-07-25 17:05:47 +01:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-11-24 16:43:18 +00:00
2020-05-11 15:45:22 +01:00
void setup ( void ) {
2020-04-17 17:27:31 +01:00
# ifdef ESP32
2020-04-18 15:34:29 +01:00
# ifdef DISABLE_ESP32_BROWNOUT
DisableBrownout ( ) ; // Workaround possible weak LDO resulting in brownout detection during Wifi connection
2020-04-17 17:27:31 +01:00
# endif
# endif
2020-04-18 15:34:29 +01:00
global_state . data = 3 ; // Init global state (wifi_down, mqtt_down) to solve possible network issues
2018-09-04 15:22:34 +01:00
RtcRebootLoad ( ) ;
2019-10-16 18:00:20 +01:00
if ( ! RtcRebootValid ( ) ) {
RtcReboot . fast_reboot_count = 0 ;
}
2018-09-04 15:22:34 +01:00
RtcReboot . fast_reboot_count + + ;
RtcRebootSave ( ) ;
2018-08-30 13:27:33 +01:00
2019-12-29 12:27:48 +00:00
Serial . begin ( APP_BAUDRATE ) ;
2020-05-11 15:45:22 +01:00
// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
2017-01-28 13:41:01 +00:00
seriallog_level = LOG_LEVEL_INFO ; // Allow specific serial messages until config loaded
2018-11-07 14:03:41 +00:00
snprintf_P ( my_version , sizeof ( my_version ) , PSTR ( " %d.%d.%d " ) , VERSION > > 24 & 0xff , VERSION > > 16 & 0xff , VERSION > > 8 & 0xff ) ; // Release version 6.3.0
if ( VERSION & 0xff ) { // Development or patched version 6.3.0.10
2018-08-17 10:10:21 +01:00
snprintf_P ( my_version , sizeof ( my_version ) , PSTR ( " %s.%d " ) , my_version , VERSION & 0xff ) ;
}
2020-01-23 09:57:29 +00:00
// Thehackbox inserts "release" or "commit number" before compiling using sed -i -e 's/PSTR("(%s)")/PSTR("(85cff52-%s)")/g' tasmota.ino
snprintf_P ( my_image , sizeof ( my_image ) , PSTR ( " (%s) " ) , CODE_IMAGE_STR ) ; // Results in (85cff52-tasmota) or (release-tasmota)
2017-10-18 17:22:34 +01:00
SettingsLoad ( ) ;
SettingsDelta ( ) ;
2017-01-28 13:41:01 +00:00
2017-10-18 17:22:34 +01:00
OsWatchInit ( ) ;
2017-02-28 15:01:48 +00:00
2018-05-17 14:36:45 +01:00
GetFeatures ( ) ;
2018-10-23 14:51:51 +01:00
if ( 1 = = RtcReboot . fast_reboot_count ) { // Allow setting override only when all is well
2019-10-18 14:18:39 +01:00
UpdateQuickPowerCycle ( true ) ;
2018-10-23 14:51:51 +01:00
XdrvCall ( FUNC_SETTINGS_OVERRIDE ) ;
}
2019-01-03 16:30:54 +00:00
// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
2017-10-18 17:22:34 +01:00
seriallog_level = Settings . seriallog_level ;
2017-08-24 10:09:52 +01:00
seriallog_timer = SERIALLOG_TIMER ;
2018-09-12 23:00:35 +01:00
syslog_level = Settings . syslog_level ;
2019-11-03 11:33:36 +00:00
stop_flash_rotate = Settings . flag . stop_flash_rotate ; // SetOption12 - Switch between dynamic or fixed slot flash save location
2017-10-18 17:22:34 +01:00
save_data_counter = Settings . save_data ;
2020-04-10 17:24:08 +01:00
ssleep = Settings . sleep ;
2018-11-16 08:36:41 +00:00
# ifndef USE_EMULATION
Settings . flag2 . emulation = 0 ;
2019-05-20 14:09:42 +01:00
# else
# ifndef USE_EMULATION_WEMO
if ( EMUL_WEMO = = Settings . flag2 . emulation ) { Settings . flag2 . emulation = 0 ; }
# endif
# ifndef USE_EMULATION_HUE
if ( EMUL_HUE = = Settings . flag2 . emulation ) { Settings . flag2 . emulation = 0 ; }
# endif
2018-11-16 08:36:41 +00:00
# endif // USE_EMULATION
2017-01-28 13:41:01 +00:00
2019-11-10 11:05:09 +00:00
if ( Settings . param [ P_BOOT_LOOP_OFFSET ] ) { // SetOption36
2019-01-30 13:34:31 +00:00
// Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts)
if ( RtcReboot . fast_reboot_count > Settings . param [ P_BOOT_LOOP_OFFSET ] ) { // Restart twice
2019-11-03 12:51:22 +00:00
Settings . flag3 . user_esp8285_enable = 0 ; // SetOption51 - Enable ESP8285 user GPIO's - Disable ESP8285 Generic GPIOs interfering with flash SPI
2019-01-30 13:34:31 +00:00
if ( RtcReboot . fast_reboot_count > Settings . param [ P_BOOT_LOOP_OFFSET ] + 1 ) { // Restart 3 times
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < MAX_RULE_SETS ; i + + ) {
2019-01-30 13:34:31 +00:00
if ( bitRead ( Settings . rule_stop , i ) ) {
bitWrite ( Settings . rule_enabled , i , 0 ) ; // Disable rules causing boot loop
}
2018-08-30 13:27:33 +01:00
}
}
2019-01-30 13:34:31 +00:00
if ( RtcReboot . fast_reboot_count > Settings . param [ P_BOOT_LOOP_OFFSET ] + 2 ) { // Restarted 4 times
Settings . rule_enabled = 0 ; // Disable all rules
2018-08-30 13:47:48 +01:00
}
2019-01-30 13:34:31 +00:00
if ( RtcReboot . fast_reboot_count > Settings . param [ P_BOOT_LOOP_OFFSET ] + 3 ) { // Restarted 5 times
2020-04-25 10:37:36 +01:00
for ( uint32_t i = 0 ; i < ARRAY_SIZE ( Settings . my_gp . io ) ; i + + ) {
2019-01-30 13:34:31 +00:00
Settings . my_gp . io [ i ] = GPIO_NONE ; // Reset user defined GPIO disabling sensors
}
2020-05-01 15:47:41 +01:00
# ifdef ESP8266
2019-05-16 17:43:23 +01:00
Settings . my_adc0 = ADC0_NONE ; // Reset user defined ADC0 disabling sensors
2020-05-01 15:47:41 +01:00
# endif
2019-01-30 13:34:31 +00:00
}
if ( RtcReboot . fast_reboot_count > Settings . param [ P_BOOT_LOOP_OFFSET ] + 4 ) { // Restarted 6 times
2020-04-10 17:24:08 +01:00
# ifdef ESP8266
2019-01-30 13:34:31 +00:00
Settings . module = SONOFF_BASIC ; // Reset module to Sonoff Basic
// Settings.last_module = SONOFF_BASIC;
2020-05-01 15:47:41 +01:00
# else // ESP32
2020-04-10 17:24:08 +01:00
Settings . module = WEMOS ; // Reset module to Wemos
2020-05-01 15:47:41 +01:00
# endif // ESP8266 - ESP32
2019-01-30 13:34:31 +00:00
}
2019-11-18 10:02:04 +00:00
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d) " ) , RtcReboot . fast_reboot_count ) ;
2018-08-28 09:26:33 +01:00
}
}
2019-12-16 14:13:57 +00:00
Format ( mqtt_client , SettingsText ( SET_MQTT_CLIENT ) , sizeof ( mqtt_client ) ) ;
Format ( mqtt_topic , SettingsText ( SET_MQTT_TOPIC ) , sizeof ( mqtt_topic ) ) ;
if ( strstr ( SettingsText ( SET_HOSTNAME ) , " % " ) ! = nullptr ) {
SettingsUpdateText ( SET_HOSTNAME , WIFI_HOSTNAME ) ;
2020-04-13 16:45:06 +01:00
snprintf_P ( my_hostname , sizeof ( my_hostname ) - 1 , SettingsText ( SET_HOSTNAME ) , mqtt_topic , ESP_getChipId ( ) & 0x1FFF ) ;
2017-01-28 13:41:01 +00:00
} else {
2019-12-16 14:13:57 +00:00
snprintf_P ( my_hostname , sizeof ( my_hostname ) - 1 , SettingsText ( SET_HOSTNAME ) ) ;
2017-01-28 13:41:01 +00:00
}
2018-09-05 14:38:48 +01:00
2019-12-02 09:31:33 +00:00
GetEspHardwareType ( ) ;
2018-09-05 14:38:48 +01:00
GpioInit ( ) ;
2019-12-30 13:23:37 +00:00
// SetSerialBaudrate(Settings.baudrate * 300); // Allow reset of serial interface if current baudrate is different from requested baudrate
2017-10-18 17:22:34 +01:00
WifiConnect ( ) ;
2017-01-28 13:41:01 +00:00
2020-01-11 14:39:56 +00:00
SetPowerOnState ( ) ;
2017-01-28 13:41:01 +00:00
2020-05-17 16:10:17 +01:00
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( D_PROJECT " %s %s " D_VERSION " %s%s- " ARDUINO_CORE_RELEASE ) , PROJECT , SettingsText ( SET_DEVICENAME ) , my_version , my_image ) ;
2019-02-08 13:55:45 +00:00
# ifdef FIRMWARE_MINIMAL
2019-03-08 14:15:42 +00:00
AddLog_P2 ( LOG_LEVEL_INFO , PSTR ( D_WARNING_MINIMAL_VERSION ) ) ;
2019-02-08 13:55:45 +00:00
# endif // FIRMWARE_MINIMAL
2017-12-01 14:59:53 +00:00
2019-12-20 14:12:44 +00:00
memcpy_P ( log_data , VERSION_MARKER , 1 ) ; // Dummy for compiler saving VERSION_MARKER
2017-12-01 14:59:53 +00:00
RtcInit ( ) ;
2018-03-21 16:58:39 +00:00
# ifdef USE_ARDUINO_OTA
ArduinoOTAInit ( ) ;
# endif // USE_ARDUINO_OTA
2018-06-04 17:10:38 +01:00
XdrvCall ( FUNC_INIT ) ;
2018-01-24 16:31:20 +00:00
XsnsCall ( FUNC_INIT ) ;
2017-01-28 13:41:01 +00:00
}
2020-05-11 15:45:22 +01:00
void BacklogLoop ( void ) {
2019-10-04 13:46:31 +01:00
if ( TimeReached ( backlog_delay ) ) {
if ( ! BACKLOG_EMPTY & & ! backlog_mutex ) {
# ifdef SUPPORT_IF_STATEMENT
2019-12-06 15:12:13 +00:00
backlog_mutex = true ;
String cmd = backlog . shift ( ) ;
backlog_mutex = false ;
ExecuteCommand ( ( char * ) cmd . c_str ( ) , SRC_BACKLOG ) ;
2019-10-04 13:46:31 +01:00
# else
2019-12-06 15:12:13 +00:00
backlog_mutex = true ;
2019-10-04 13:46:31 +01:00
ExecuteCommand ( ( char * ) backlog [ backlog_pointer ] . c_str ( ) , SRC_BACKLOG ) ;
backlog_pointer + + ;
if ( backlog_pointer > = MAX_BACKLOG ) { backlog_pointer = 0 ; }
backlog_mutex = false ;
2019-12-06 15:12:13 +00:00
# endif
2019-10-04 13:46:31 +01:00
}
}
}
2020-05-11 15:45:22 +01:00
void SleepDelay ( uint32_t mseconds ) {
if ( mseconds ) {
for ( uint32_t wait = 0 ; wait < mseconds ; wait + + ) {
delay ( 1 ) ;
if ( Serial . available ( ) ) { break ; } // We need to service serial buffer ASAP as otherwise we get uart buffer overrun
}
} else {
delay ( 0 ) ;
}
}
void loop ( void ) {
2018-11-18 14:02:52 +00:00
uint32_t my_sleep = millis ( ) ;
2018-02-27 13:59:46 +00:00
XdrvCall ( FUNC_LOOP ) ;
2018-12-11 13:24:52 +00:00
XsnsCall ( FUNC_LOOP ) ;
2018-02-27 13:59:46 +00:00
2017-10-18 17:22:34 +01:00
OsWatchLoop ( ) ;
2017-09-02 13:37:02 +01:00
2019-01-07 11:38:47 +00:00
ButtonLoop ( ) ;
2018-12-28 15:35:19 +00:00
SwitchLoop ( ) ;
2019-04-05 14:27:06 +01:00
# ifdef ROTARY_V1
2019-01-11 00:50:40 +00:00
RotaryLoop ( ) ;
2019-04-05 14:27:06 +01:00
# endif
2020-02-21 15:09:21 +00:00
# ifdef USE_DEVICE_GROUPS
DeviceGroupsLoop ( ) ;
# endif // USE_DEVICE_GROUPS
2019-10-09 16:52:52 +01:00
BacklogLoop ( ) ;
2018-12-28 15:35:19 +00:00
2018-08-26 14:42:35 +01:00
if ( TimeReached ( state_50msecond ) ) {
SetNextTimeInterval ( state_50msecond , 50 ) ;
2018-08-26 16:10:18 +01:00
XdrvCall ( FUNC_EVERY_50_MSECOND ) ;
XsnsCall ( FUNC_EVERY_50_MSECOND ) ;
2018-08-26 14:42:35 +01:00
}
if ( TimeReached ( state_100msecond ) ) {
SetNextTimeInterval ( state_100msecond , 100 ) ;
Every100mSeconds ( ) ;
2018-08-26 16:10:18 +01:00
XdrvCall ( FUNC_EVERY_100_MSECOND ) ;
XsnsCall ( FUNC_EVERY_100_MSECOND ) ;
2018-08-26 14:42:35 +01:00
}
if ( TimeReached ( state_250msecond ) ) {
SetNextTimeInterval ( state_250msecond , 250 ) ;
Every250mSeconds ( ) ;
2018-08-26 16:10:18 +01:00
XdrvCall ( FUNC_EVERY_250_MSECOND ) ;
XsnsCall ( FUNC_EVERY_250_MSECOND ) ;
2019-10-18 11:47:22 +01:00
}
if ( TimeReached ( state_second ) ) {
SetNextTimeInterval ( state_second , 1000 ) ;
PerformEverySecond ( ) ;
XdrvCall ( FUNC_EVERY_SECOND ) ;
XsnsCall ( FUNC_EVERY_SECOND ) ;
2018-08-26 14:42:35 +01:00
}
2018-02-27 13:59:46 +00:00
2019-01-28 13:08:33 +00:00
if ( ! serial_local ) { SerialInput ( ) ; }
2017-01-28 13:41:01 +00:00
2018-03-21 16:58:39 +00:00
# ifdef USE_ARDUINO_OTA
2020-01-03 15:50:56 +00:00
ArduinoOtaLoop ( ) ;
2018-03-21 16:58:39 +00:00
# endif // USE_ARDUINO_OTA
2018-11-18 14:02:52 +00:00
uint32_t my_activity = millis ( ) - my_sleep ;
2018-12-01 17:53:42 +00:00
2020-05-11 15:45:22 +01:00
if ( Settings . flag3 . sleep_normal ) { // SetOption60 - Enable normal sleep instead of dynamic sleep
// yield(); // yield == delay(0), delay contains yield, auto yield in loop
SleepDelay ( ssleep ) ; // https://github.com/esp8266/Arduino/issues/2021
2018-11-22 11:25:18 +00:00
} else {
2020-04-10 17:24:08 +01:00
if ( my_activity < ( uint32_t ) ssleep ) {
2020-05-11 15:45:22 +01:00
SleepDelay ( ( uint32_t ) ssleep - my_activity ) ; // Provide time for background tasks like wifi
2018-12-01 16:47:25 +00:00
} else {
if ( global_state . wifi_down ) {
2020-05-11 15:45:22 +01:00
SleepDelay ( my_activity / 2 ) ; // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period
2018-12-01 16:47:25 +00:00
}
2018-11-22 11:25:18 +00:00
}
}
2018-11-25 16:31:53 +00:00
2020-05-11 15:45:22 +01:00
if ( ! my_activity ) { my_activity + + ; } // We cannot divide by 0
2020-04-10 17:24:08 +01:00
uint32_t loop_delay = ssleep ;
2020-05-11 15:45:22 +01:00
if ( ! loop_delay ) { loop_delay + + ; } // We cannot divide by 0
uint32_t loops_per_second = 1000 / loop_delay ; // We need to keep track of this many loops per second
2018-11-25 16:31:53 +00:00
uint32_t this_cycle_ratio = 100 * my_activity / loop_delay ;
2018-12-01 16:47:25 +00:00
loop_load_avg = loop_load_avg - ( loop_load_avg / loops_per_second ) + ( this_cycle_ratio / loops_per_second ) ; // Take away one loop average away and add the new one
2017-08-08 15:08:08 +01:00
}