* Config: remove prototypes.h * fixup order * word * add missing * fix warning while still using .ino * bad at c/p;mcspr-patch-1
@ -0,0 +1,28 @@ | |||
/* | |||
ALEXA MODULE | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#include "web.h" | |||
struct alexa_queue_element_t { | |||
unsigned char device_id; | |||
bool state; | |||
unsigned char value; | |||
}; | |||
#if ALEXA_SUPPORT | |||
#include <fauxmoESP.h> | |||
#include <ArduinoJson.h> | |||
bool alexaEnabled(); | |||
void alexaSetup(); | |||
#endif // ALEXA_SUPPORT == 1 | |||
@ -0,0 +1,31 @@ | |||
/* | |||
API MODULE | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#include "web.h" | |||
#include <functional> | |||
// TODO: need these prototypes for .ino | |||
using api_get_callback_f = std::function<void(char * buffer, size_t size)>; | |||
using api_put_callback_f = std::function<void(const char * payload)> ; | |||
#if API_SUPPORT | |||
#include <ESPAsyncTCP.h> | |||
#include <ESPAsyncWebServer.h> | |||
#include <ArduinoJson.h> | |||
#include <vector> | |||
#if WEB_SUPPORT | |||
void apiRegister(const char * key, api_get_callback_f getFn, api_put_callback_f putFn = nullptr); | |||
#endif | |||
#endif // API_SUPPORT == 1 |
@ -0,0 +1,87 @@ | |||
/* | |||
COMPATIBILITY BETWEEN 2.3.0 and latest versions | |||
*/ | |||
#pragma once | |||
// ----------------------------------------------------------------------------- | |||
// Core version 2.4.2 and higher changed the cont_t structure to a pointer: | |||
// https://github.com/esp8266/Arduino/commit/5d5ea92a4d004ab009d5f642629946a0cb8893dd#diff-3fa12668b289ccb95b7ab334833a4ba8L35 | |||
// Core version 2.5.0 introduced EspClass helper method: | |||
// https://github.com/esp8266/Arduino/commit/0e0e34c614fe8a47544c9998201b1d9b3c24eb18 | |||
// ----------------------------------------------------------------------------- | |||
extern "C" { | |||
#include <cont.h> | |||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_1) | |||
extern cont_t g_cont; | |||
#define getFreeStack() cont_get_free_stack(&g_cont) | |||
#elif defined(ARDUINO_ESP8266_RELEASE_2_4_2) | |||
extern cont_t* g_pcont; | |||
#define getFreeStack() cont_get_free_stack(g_pcont) | |||
#else | |||
#define getFreeStack() ESP.getFreeContStack() | |||
#endif | |||
} | |||
#include <pgmspace.h> | |||
// ----------------------------------------------------------------------------- | |||
// ref: https://github.com/esp8266/Arduino/blob/master/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h | |||
// __STRINGIZE && __STRINGIZE_NX && PROGMEM definitions port | |||
// ----------------------------------------------------------------------------- | |||
// Do not replace macros unless running version older than 2.5.0 | |||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_1) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_2) | |||
// Quoting esp8266/Arduino comments: | |||
// "Since __section__ is supposed to be only use for global variables, | |||
// there could be conflicts when a static/inlined function has them in the | |||
// same file as a non-static PROGMEM object. | |||
// Ref: https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html | |||
// Place each progmem object into its own named section, avoiding conflicts" | |||
#define __TO_STR_(A) #A | |||
#define __TO_STR(A) __TO_STR_(A) | |||
#undef PROGMEM | |||
#define PROGMEM __attribute__((section( "\".irom.text." __FILE__ "." __TO_STR(__LINE__) "." __TO_STR(__COUNTER__) "\""))) | |||
// "PSTR() macro modified to start on a 32-bit boundary. This adds on average | |||
// 1.5 bytes/string, but in return memcpy_P and strcpy_P will work 4~8x faster" | |||
#undef PSTR | |||
#define PSTR(s) (__extension__({static const char __c[] __attribute__((__aligned__(4))) PROGMEM = (s); &__c[0];})) | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// Division by zero bug | |||
// https://github.com/esp8266/Arduino/pull/2397 | |||
// https://github.com/esp8266/Arduino/pull/2408 | |||
// ----------------------------------------------------------------------------- | |||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) | |||
long __attribute__((deprecated("Please avoid using map() with Core 2.3.0"))) map(long x, long in_min, long in_max, long out_min, long out_max); | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// std::make_unique backport for C++11, since we still use it | |||
// ----------------------------------------------------------------------------- | |||
#if 201103L >= __cplusplus | |||
namespace std { | |||
template<typename T, typename... Args> | |||
std::unique_ptr<T> make_unique(Args&&... args) { | |||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | |||
} | |||
} | |||
#endif | |||
#define UNUSED(x) (void)(x) | |||
@ -1,395 +0,0 @@ | |||
//-------------------------------------------------------------------------------- | |||
// PROGMEM definitions | |||
//-------------------------------------------------------------------------------- | |||
//-------------------------------------------------------------------------------- | |||
// Various strings | |||
//-------------------------------------------------------------------------------- | |||
PROGMEM const char pstr_unknown[] = "UNKNOWN"; | |||
//-------------------------------------------------------------------------------- | |||
// Reset reasons | |||
//-------------------------------------------------------------------------------- | |||
PROGMEM const char custom_reset_hardware[] = "Hardware button"; | |||
PROGMEM const char custom_reset_web[] = "Reboot from web interface"; | |||
PROGMEM const char custom_reset_terminal[] = "Reboot from terminal"; | |||
PROGMEM const char custom_reset_mqtt[] = "Reboot from MQTT"; | |||
PROGMEM const char custom_reset_rpc[] = "Reboot from RPC"; | |||
PROGMEM const char custom_reset_ota[] = "Reboot after successful OTA update"; | |||
PROGMEM const char custom_reset_http[] = "Reboot from HTTP"; | |||
PROGMEM const char custom_reset_nofuss[] = "Reboot after successful NoFUSS update"; | |||
PROGMEM const char custom_reset_upgrade[] = "Reboot after successful web update"; | |||
PROGMEM const char custom_reset_factory[] = "Factory reset"; | |||
PROGMEM const char* const custom_reset_string[] = { | |||
custom_reset_hardware, custom_reset_web, custom_reset_terminal, | |||
custom_reset_mqtt, custom_reset_rpc, custom_reset_ota, | |||
custom_reset_http, custom_reset_nofuss, custom_reset_upgrade, | |||
custom_reset_factory | |||
}; | |||
//-------------------------------------------------------------------------------- | |||
// Capabilities | |||
//-------------------------------------------------------------------------------- | |||
PROGMEM const char espurna_modules[] = | |||
#if ALEXA_SUPPORT | |||
"ALEXA " | |||
#endif | |||
#if API_SUPPORT | |||
"API " | |||
#endif | |||
#if BROKER_SUPPORT | |||
"BROKER " | |||
#endif | |||
#if BUTTON_SUPPORT | |||
"BUTTON " | |||
#endif | |||
#if DEBUG_SERIAL_SUPPORT | |||
"DEBUG_SERIAL " | |||
#endif | |||
#if DEBUG_TELNET_SUPPORT | |||
"DEBUG_TELNET " | |||
#endif | |||
#if DEBUG_UDP_SUPPORT | |||
"DEBUG_UDP " | |||
#endif | |||
#if DEBUG_WEB_SUPPORT | |||
"DEBUG_WEB " | |||
#endif | |||
#if DOMOTICZ_SUPPORT | |||
"DOMOTICZ " | |||
#endif | |||
#if ENCODER_SUPPORT | |||
"ENCODER " | |||
#endif | |||
#if HOMEASSISTANT_SUPPORT | |||
"HOMEASSISTANT " | |||
#endif | |||
#if I2C_SUPPORT | |||
"I2C " | |||
#endif | |||
#if INFLUXDB_SUPPORT | |||
"INFLUXDB " | |||
#endif | |||
#if IR_SUPPORT | |||
"IR " | |||
#endif | |||
#if LED_SUPPORT | |||
"LED " | |||
#endif | |||
#if LLMNR_SUPPORT | |||
"LLMNR " | |||
#endif | |||
#if MDNS_CLIENT_SUPPORT | |||
"MDNS_CLIENT " | |||
#endif | |||
#if MDNS_SERVER_SUPPORT | |||
"MDNS_SERVER " | |||
#endif | |||
#if MQTT_SUPPORT | |||
"MQTT " | |||
#endif | |||
#if NETBIOS_SUPPORT | |||
"NETBIOS " | |||
#endif | |||
#if NOFUSS_SUPPORT | |||
"NOFUSS " | |||
#endif | |||
#if NTP_SUPPORT | |||
"NTP " | |||
#endif | |||
#if RFM69_SUPPORT | |||
"RFM69 " | |||
#endif | |||
#if RF_SUPPORT | |||
"RF " | |||
#endif | |||
#if SCHEDULER_SUPPORT | |||
"SCHEDULER " | |||
#endif | |||
#if SENSOR_SUPPORT | |||
"SENSOR " | |||
#endif | |||
#if SPIFFS_SUPPORT | |||
"SPIFFS " | |||
#endif | |||
#if SSDP_SUPPORT | |||
"SSDP " | |||
#endif | |||
#if TELNET_SUPPORT | |||
#if TELNET_SERVER == TELNET_SERVER_WIFISERVER | |||
"TELNET_SYNC " | |||
#else | |||
"TELNET " | |||
#endif // TELNET_SERVER == TELNET_SERVER_WIFISERVER | |||
#endif | |||
#if TERMINAL_SUPPORT | |||
"TERMINAL " | |||
#endif | |||
#if THERMOSTAT_SUPPORT | |||
"THERMOSTAT " | |||
#endif | |||
#if THERMOSTAT_DISPLAY_SUPPORT | |||
"THERMOSTAT_DISPLAY " | |||
#endif | |||
#if THINGSPEAK_SUPPORT | |||
"THINGSPEAK " | |||
#endif | |||
#if UART_MQTT_SUPPORT | |||
"UART_MQTT " | |||
#endif | |||
#if WEB_SUPPORT | |||
"WEB " | |||
#endif | |||
""; | |||
PROGMEM const char espurna_ota_modules[] = | |||
#if OTA_ARDUINOOTA_SUPPORT | |||
"ARDUINO " | |||
#endif | |||
#if (OTA_CLIENT == OTA_CLIENT_ASYNCTCP) | |||
"ASYNCTCP " | |||
#endif | |||
#if (OTA_CLIENT == OTA_CLIENT_HTTPUPDATE) | |||
#if (SECURE_CLIENT == SECURE_CLIENT_NONE) | |||
"*HTTPUPDATE " | |||
#endif | |||
#if (SECURE_CLIENT == SECURE_CLIENT_AXTLS) | |||
"*HTTPUPDATE_AXTLS " | |||
#endif | |||
#if (SECURE_CLIENT == SECURE_CLIENT_BEARSSL) | |||
"*HTTPUPDATE_BEARSSL " | |||
#endif | |||
#endif // OTA_CLIENT_HTTPUPDATE | |||
#if OTA_MQTT_SUPPORT | |||
"MQTT " | |||
#endif | |||
#if WEB_SUPPORT | |||
"WEB " | |||
#endif | |||
""; | |||
//-------------------------------------------------------------------------------- | |||
// Sensors | |||
//-------------------------------------------------------------------------------- | |||
#if SENSOR_SUPPORT | |||
PROGMEM const char espurna_sensors[] = | |||
#if AM2320_SUPPORT | |||
"AM2320_I2C " | |||
#endif | |||
#if ANALOG_SUPPORT | |||
"ANALOG " | |||
#endif | |||
#if BH1750_SUPPORT | |||
"BH1750 " | |||
#endif | |||
#if BMP180_SUPPORT | |||
"BMP180 " | |||
#endif | |||
#if BMX280_SUPPORT | |||
"BMX280 " | |||
#endif | |||
#if CSE7766_SUPPORT | |||
"CSE7766 " | |||
#endif | |||
#if DALLAS_SUPPORT | |||
"DALLAS " | |||
#endif | |||
#if DHT_SUPPORT | |||
"DHTXX " | |||
#endif | |||
#if DIGITAL_SUPPORT | |||
"DIGITAL " | |||
#endif | |||
#if ECH1560_SUPPORT | |||
"ECH1560 " | |||
#endif | |||
#if EMON_ADC121_SUPPORT | |||
"EMON_ADC121 " | |||
#endif | |||
#if EMON_ADS1X15_SUPPORT | |||
"EMON_ADX1X15 " | |||
#endif | |||
#if EMON_ANALOG_SUPPORT | |||
"EMON_ANALOG " | |||
#endif | |||
#if EVENTS_SUPPORT | |||
"EVENTS " | |||
#endif | |||
#if GEIGER_SUPPORT | |||
"GEIGER " | |||
#endif | |||
#if GUVAS12SD_SUPPORT | |||
"GUVAS12SD " | |||
#endif | |||
#if HLW8012_SUPPORT | |||
"HLW8012 " | |||
#endif | |||
#if LDR_SUPPORT | |||
"LDR " | |||
#endif | |||
#if MHZ19_SUPPORT | |||
"MHZ19 " | |||
#endif | |||
#if MICS2710_SUPPORT | |||
"MICS2710 " | |||
#endif | |||
#if MICS5525_SUPPORT | |||
"MICS5525 " | |||
#endif | |||
#if NTC_SUPPORT | |||
"NTC " | |||
#endif | |||
#if PMSX003_SUPPORT | |||
"PMSX003 " | |||
#endif | |||
#if PULSEMETER_SUPPORT | |||
"PULSEMETER " | |||
#endif | |||
#if PZEM004T_SUPPORT | |||
"PZEM004T " | |||
#endif | |||
#if SDS011_SUPPORT | |||
"SDS011 " | |||
#endif | |||
#if SENSEAIR_SUPPORT | |||
"SENSEAIR " | |||
#endif | |||
#if SHT3X_I2C_SUPPORT | |||
"SHT3X_I2C " | |||
#endif | |||
#if SI7021_SUPPORT | |||
"SI7021 " | |||
#endif | |||
#if SONAR_SUPPORT | |||
"SONAR " | |||
#endif | |||
#if T6613_SUPPORT | |||
"T6613 " | |||
#endif | |||
#if TMP3X_SUPPORT | |||
"TMP3X " | |||
#endif | |||
#if V9261F_SUPPORT | |||
"V9261F " | |||
#endif | |||
#if VEML6075_SUPPORT | |||
"VEML6075 " | |||
#endif | |||
#if VL53L1X_SUPPORT | |||
"VL53L1X " | |||
#endif | |||
#if EZOPH_SUPPORT | |||
"EZOPH " | |||
#endif | |||
#if ADE7953_SUPPORT | |||
"ADE7953 " | |||
#endif | |||
""; | |||
PROGMEM const unsigned char magnitude_decimals[] = { | |||
0, | |||
1, 0, 2, // THP | |||
3, 0, 0, 0, 0, 0, 0, 0, // Power decimals | |||
0, 0, 0, // analog, digital, event | |||
0, 0, 0, // PM | |||
0, 0, | |||
0, 0, 3, // UVA, UVB, UVI | |||
3, 0, | |||
4, 4, // Geiger Counter decimals | |||
0, | |||
0, 0, 0, 3 // NO2, CO, Ohms, pH | |||
}; | |||
PROGMEM const char magnitude_unknown_topic[] = "unknown"; | |||
PROGMEM const char magnitude_temperature_topic[] = "temperature"; | |||
PROGMEM const char magnitude_humidity_topic[] = "humidity"; | |||
PROGMEM const char magnitude_pressure_topic[] = "pressure"; | |||
PROGMEM const char magnitude_current_topic[] = "current"; | |||
PROGMEM const char magnitude_voltage_topic[] = "voltage"; | |||
PROGMEM const char magnitude_active_power_topic[] = "power"; | |||
PROGMEM const char magnitude_apparent_power_topic[] = "apparent"; | |||
PROGMEM const char magnitude_reactive_power_topic[] = "reactive"; | |||
PROGMEM const char magnitude_power_factor_topic[] = "factor"; | |||
PROGMEM const char magnitude_energy_topic[] = "energy"; | |||
PROGMEM const char magnitude_energy_delta_topic[] = "energy_delta"; | |||
PROGMEM const char magnitude_analog_topic[] = "analog"; | |||
PROGMEM const char magnitude_digital_topic[] = "digital"; | |||
PROGMEM const char magnitude_event_topic[] = "event"; | |||
PROGMEM const char magnitude_pm1dot0_topic[] = "pm1dot0"; | |||
PROGMEM const char magnitude_pm2dot5_topic[] = "pm2dot5"; | |||
PROGMEM const char magnitude_pm10_topic[] = "pm10"; | |||
PROGMEM const char magnitude_co2_topic[] = "co2"; | |||
PROGMEM const char magnitude_lux_topic[] = "lux"; | |||
PROGMEM const char magnitude_uva_topic[] = "uva"; | |||
PROGMEM const char magnitude_uvb_topic[] = "uvb"; | |||
PROGMEM const char magnitude_uvi_topic[] = "uvi"; | |||
PROGMEM const char magnitude_distance_topic[] = "distance"; | |||
PROGMEM const char magnitude_hcho_topic[] = "hcho"; | |||
PROGMEM const char magnitude_geiger_cpm_topic[] = "ldr_cpm"; // local dose rate [Counts per minute] | |||
PROGMEM const char magnitude_geiger_sv_topic[] = "ldr_uSvh"; // local dose rate [µSievert per hour] | |||
PROGMEM const char magnitude_count_topic[] = "count"; | |||
PROGMEM const char magnitude_no2_topic[] = "no2"; | |||
PROGMEM const char magnitude_co_topic[] = "co"; | |||
PROGMEM const char magnitude_resistance_topic[] = "resistance"; | |||
PROGMEM const char magnitude_ph_topic[] = "ph"; | |||
PROGMEM const char* const magnitude_topics[] = { | |||
magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic, | |||
magnitude_pressure_topic, magnitude_current_topic, magnitude_voltage_topic, | |||
magnitude_active_power_topic, magnitude_apparent_power_topic, magnitude_reactive_power_topic, | |||
magnitude_power_factor_topic, magnitude_energy_topic, magnitude_energy_delta_topic, | |||
magnitude_analog_topic, magnitude_digital_topic, magnitude_event_topic, | |||
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic, | |||
magnitude_co2_topic, magnitude_lux_topic, | |||
magnitude_uva_topic, magnitude_uvb_topic, magnitude_uvi_topic, | |||
magnitude_distance_topic, magnitude_hcho_topic, | |||
magnitude_geiger_cpm_topic, magnitude_geiger_sv_topic, | |||
magnitude_count_topic, | |||
magnitude_no2_topic, magnitude_co_topic, magnitude_resistance_topic, magnitude_ph_topic | |||
}; | |||
PROGMEM const char magnitude_empty[] = ""; | |||
PROGMEM const char magnitude_celsius[] = "°C"; | |||
PROGMEM const char magnitude_fahrenheit[] = "°F"; | |||
PROGMEM const char magnitude_percentage[] = "%"; | |||
PROGMEM const char magnitude_hectopascals[] = "hPa"; | |||
PROGMEM const char magnitude_amperes[] = "A"; | |||
PROGMEM const char magnitude_volts[] = "V"; | |||
PROGMEM const char magnitude_watts[] = "W"; | |||
PROGMEM const char magnitude_kw[] = "kW"; | |||
PROGMEM const char magnitude_joules[] = "J"; | |||
PROGMEM const char magnitude_kwh[] = "kWh"; | |||
PROGMEM const char magnitude_ugm3[] = "µg/m³"; | |||
PROGMEM const char magnitude_ppm[] = "ppm"; | |||
PROGMEM const char magnitude_lux[] = "lux"; | |||
PROGMEM const char magnitude_distance[] = "m"; | |||
PROGMEM const char magnitude_mgm3[] = "mg/m³"; | |||
PROGMEM const char magnitude_geiger_cpm[] = "cpm"; // Counts per Minute: Unit of local dose rate (Geiger counting) | |||
PROGMEM const char magnitude_geiger_sv[] = "µSv/h"; // µSievert per hour: 2nd unit of local dose rate (Geiger counting) | |||
PROGMEM const char magnitude_resistance[] = "ohm"; | |||
PROGMEM const char* const magnitude_units[] = { | |||
magnitude_empty, magnitude_celsius, magnitude_percentage, | |||
magnitude_hectopascals, magnitude_amperes, magnitude_volts, | |||
magnitude_watts, magnitude_watts, magnitude_watts, | |||
magnitude_percentage, magnitude_joules, magnitude_joules, | |||
magnitude_empty, magnitude_empty, magnitude_empty, | |||
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, | |||
magnitude_ppm, magnitude_lux, | |||
magnitude_empty, magnitude_empty, magnitude_empty, | |||
magnitude_distance, magnitude_mgm3, | |||
magnitude_geiger_cpm, magnitude_geiger_sv, // Geiger counter units | |||
magnitude_empty, // | |||
magnitude_ppm, magnitude_ppm, // NO2 & CO2 | |||
magnitude_resistance, | |||
magnitude_empty // pH | |||
}; | |||
#endif |
@ -1,319 +0,0 @@ | |||
#include <Arduino.h> | |||
#include <ArduinoJson.h> | |||
#include <functional> | |||
#include <algorithm> | |||
#include <limits> | |||
#include <vector> | |||
#include <memory> | |||
extern "C" { | |||
#include "user_interface.h" | |||
extern struct rst_info resetInfo; | |||
} | |||
#define UNUSED(x) (void)(x) | |||
// ----------------------------------------------------------------------------- | |||
// System | |||
// ----------------------------------------------------------------------------- | |||
#define LWIP_INTERNAL | |||
#include <ESP8266WiFi.h> | |||
#undef LWIP_INTERNAL | |||
extern "C" { | |||
#include <lwip/opt.h> | |||
#include <lwip/ip.h> | |||
#include <lwip/tcp.h> | |||
#include <lwip/inet.h> // ip_addr_t | |||
#include <lwip/err.h> // ERR_x | |||
#include <lwip/dns.h> // dns_gethostbyname | |||
#include <lwip/ip_addr.h> // ip4/ip6 helpers | |||
#include <lwip/init.h> // LWIP_VERSION_MAJOR | |||
} | |||
// ref: https://github.com/me-no-dev/ESPAsyncTCP/pull/115/files#diff-e2e636049095cc1ff920c1bfabf6dcacR8 | |||
// This is missing with Core 2.3.0 and is sometimes missing from the build flags. Assume HIGH_BANDWIDTH version. | |||
#ifndef TCP_MSS | |||
#define TCP_MSS (1460) | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// PROGMEM | |||
// ----------------------------------------------------------------------------- | |||
#include <pgmspace.h> | |||
// ref: https://github.com/esp8266/Arduino/blob/master/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h | |||
// __STRINGIZE && __STRINGIZE_NX && PROGMEM definitions port | |||
// Do not replace macros unless running version older than 2.5.0 | |||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_1) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_2) | |||
// Quoting esp8266/Arduino comments: | |||
// "Since __section__ is supposed to be only use for global variables, | |||
// there could be conflicts when a static/inlined function has them in the | |||
// same file as a non-static PROGMEM object. | |||
// Ref: https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html | |||
// Place each progmem object into its own named section, avoiding conflicts" | |||
#define __TO_STR_(A) #A | |||
#define __TO_STR(A) __TO_STR_(A) | |||
#undef PROGMEM | |||
#define PROGMEM __attribute__((section( "\".irom.text." __FILE__ "." __TO_STR(__LINE__) "." __TO_STR(__COUNTER__) "\""))) | |||
// "PSTR() macro modified to start on a 32-bit boundary. This adds on average | |||
// 1.5 bytes/string, but in return memcpy_P and strcpy_P will work 4~8x faster" | |||
#undef PSTR | |||
#define PSTR(s) (__extension__({static const char __c[] __attribute__((__aligned__(4))) PROGMEM = (s); &__c[0];})) | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// API | |||
// ----------------------------------------------------------------------------- | |||
using api_get_callback_f = std::function<void(char * buffer, size_t size)>; | |||
using api_put_callback_f = std::function<void(const char * payload)> ; | |||
#if WEB_SUPPORT | |||
void apiRegister(const char * key, api_get_callback_f getFn, api_put_callback_f putFn = NULL); | |||
#endif | |||
// Core version 2.4.2 and higher changed the cont_t structure to a pointer: | |||
// https://github.com/esp8266/Arduino/commit/5d5ea92a4d004ab009d5f642629946a0cb8893dd#diff-3fa12668b289ccb95b7ab334833a4ba8L35 | |||
// Core version 2.5.0 introduced EspClass helper method: | |||
// https://github.com/esp8266/Arduino/commit/0e0e34c614fe8a47544c9998201b1d9b3c24eb18 | |||
extern "C" { | |||
#include <cont.h> | |||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_0) \ | |||
|| defined(ARDUINO_ESP8266_RELEASE_2_4_1) | |||
extern cont_t g_cont; | |||
#define getFreeStack() cont_get_free_stack(&g_cont) | |||
#elif defined(ARDUINO_ESP8266_RELEASE_2_4_2) | |||
extern cont_t* g_pcont; | |||
#define getFreeStack() cont_get_free_stack(g_pcont) | |||
#else | |||
#define getFreeStack() ESP.getFreeContStack() | |||
#endif | |||
} | |||
void infoMemory(const char* , unsigned int, unsigned int); | |||
unsigned int getFreeHeap(); | |||
unsigned int getInitialFreeHeap(); | |||
// ----------------------------------------------------------------------------- | |||
// Domoticz | |||
// ----------------------------------------------------------------------------- | |||
#if DOMOTICZ_SUPPORT | |||
template<typename T> void domoticzSend(const char * key, T value); | |||
template<typename T> void domoticzSend(const char * key, T nvalue, const char * svalue); | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// EEPROM_ROTATE | |||
// ----------------------------------------------------------------------------- | |||
#include <EEPROM_Rotate.h> | |||
EEPROM_Rotate EEPROMr; | |||
void eepromSectorsDebug(); | |||
// ----------------------------------------------------------------------------- | |||
// GPIO | |||
// ----------------------------------------------------------------------------- | |||
bool gpioValid(unsigned char gpio); | |||
bool gpioGetLock(unsigned char gpio); | |||
bool gpioReleaseLock(unsigned char gpio); | |||
// ----------------------------------------------------------------------------- | |||
// Homeassistant | |||
// ----------------------------------------------------------------------------- | |||
struct ha_config_t; | |||
void haSetup(); | |||
// ----------------------------------------------------------------------------- | |||
// I2C | |||
// ----------------------------------------------------------------------------- | |||
void i2cScan(); | |||
void i2cClearBus(); | |||
bool i2cGetLock(unsigned char address); | |||
bool i2cReleaseLock(unsigned char address); | |||
unsigned char i2cFindAndLock(size_t size, unsigned char * addresses); | |||
void i2c_wakeup(uint8_t address); | |||
uint8_t i2c_write_buffer(uint8_t address, uint8_t * buffer, size_t len); | |||
uint8_t i2c_write_uint8(uint8_t address, uint8_t value); | |||
uint8_t i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value); | |||
uint8_t i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value1, uint8_t value2); | |||
uint8_t i2c_write_uint16(uint8_t address, uint16_t value); | |||
uint8_t i2c_write_uint16(uint8_t address, uint8_t reg, uint16_t value); | |||
uint8_t i2c_read_uint8(uint8_t address); | |||
uint8_t i2c_read_uint8(uint8_t address, uint8_t reg); | |||
uint16_t i2c_read_uint16(uint8_t address); | |||
uint16_t i2c_read_uint16(uint8_t address, uint8_t reg); | |||
uint16_t i2c_read_uint16_le(uint8_t address, uint8_t reg); | |||
int16_t i2c_read_int16(uint8_t address, uint8_t reg); | |||
int16_t i2c_read_int16_le(uint8_t address, uint8_t reg); | |||
void i2c_read_buffer(uint8_t address, uint8_t * buffer, size_t len); | |||
// ----------------------------------------------------------------------------- | |||
// MQTT | |||
// ----------------------------------------------------------------------------- | |||
#if MQTT_LIBRARY == MQTT_LIBRARY_ASYNCMQTTCLIENT | |||
#include <ESPAsyncTCP.h> | |||
#include <AsyncMqttClient.h> | |||
#elif MQTT_LIBRARY == MQTT_LIBRARY_ARDUINOMQTT | |||
#include <MQTTClient.h> | |||
#elif MQTT_LIBRARY == MQTT_LIBRARY_PUBSUBCLIENT | |||
#include <PubSubClient.h> | |||
#endif | |||
using mqtt_callback_f = std::function<void(unsigned int type, const char * topic, char * payload)>; | |||
using mqtt_msg_t = std::pair<String, String>; // topic, payload | |||
void mqttRegister(mqtt_callback_f callback); | |||
String mqttTopic(const char * magnitude, bool is_set); | |||
String mqttTopic(const char * magnitude, unsigned int index, bool is_set); | |||
String mqttMagnitude(char * topic); | |||
bool mqttSendRaw(const char * topic, const char * message, bool retain); | |||
bool mqttSendRaw(const char * topic, const char * message); | |||
void mqttSend(const char * topic, const char * message, bool force, bool retain); | |||
void mqttSend(const char * topic, const char * message, bool force); | |||
void mqttSend(const char * topic, const char * message); | |||
void mqttSend(const char * topic, unsigned int index, const char * message, bool force); | |||
void mqttSend(const char * topic, unsigned int index, const char * message); | |||
const String& mqttPayloadOnline(); | |||
const String& mqttPayloadOffline(); | |||
const char* mqttPayloadStatus(bool status); | |||
void mqttSendStatus(); | |||
// ----------------------------------------------------------------------------- | |||
// OTA | |||
// ----------------------------------------------------------------------------- | |||
#include <ArduinoOTA.h> | |||
#if OTA_CLIENT == OTA_CLIENT_ASYNCTCP | |||
#include <ESPAsyncTCP.h> | |||
#endif | |||
#if OTA_CLIENT == OTA_CLIENT_HTTPUPDATE | |||
#include <ESP8266HTTPClient.h> | |||
#include <ESP8266httpUpdate.h> | |||
#endif | |||
#if SECURE_CLIENT != SECURE_CLIENT_NONE | |||
#include <WiFiClientSecure.h> | |||
#endif // SECURE_CLIENT != SECURE_CLIENT_NONE | |||
// ----------------------------------------------------------------------------- | |||
// RFM69 | |||
// ----------------------------------------------------------------------------- | |||
typedef struct { | |||
unsigned long messageID; | |||
unsigned char packetID; | |||
unsigned char senderID; | |||
unsigned char targetID; | |||
char * key; | |||
char * value; | |||
int16_t rssi; | |||
} packet_t; | |||
// ----------------------------------------------------------------------------- | |||
// Terminal | |||
// ----------------------------------------------------------------------------- | |||
class Embedis; // FIXME: order | |||
using embedis_command_f = void (*)(Embedis*); | |||
void terminalRegisterCommand(const String& name, embedis_command_f func); | |||
void terminalInject(void *data, size_t len); | |||
Stream& terminalSerial(); | |||
// ----------------------------------------------------------------------------- | |||
// WebServer | |||
// ----------------------------------------------------------------------------- | |||
class AsyncClient; | |||
class AsyncWebServer; | |||
#if WEB_SUPPORT | |||
#include <ESPAsyncWebServer.h> | |||
AsyncWebServer * webServer(); | |||
#else | |||
class AsyncWebServerRequest; | |||
class ArRequestHandlerFunction; | |||
class AsyncWebSocketClient; | |||
class AsyncWebSocket; | |||
class AwsEventType; | |||
#endif | |||
using web_body_callback_f = std::function<bool(AsyncWebServerRequest*, uint8_t* data, size_t len, size_t index, size_t total)>; | |||
using web_request_callback_f = std::function<bool(AsyncWebServerRequest*)>; | |||
void webBodyRegister(web_body_callback_f); | |||
void webRequestRegister(web_request_callback_f); | |||
// ----------------------------------------------------------------------------- | |||
// WIFI | |||
// ----------------------------------------------------------------------------- | |||
#include <JustWifi.h> | |||
struct wifi_scan_info_t; | |||
using wifi_scan_f = std::function<void(wifi_scan_info_t& info)>; | |||
using wifi_callback_f = std::function<void(justwifi_messages_t code, char * parameter)>; | |||
void wifiRegister(wifi_callback_f callback); | |||
bool wifiConnected(); | |||
#if LWIP_VERSION_MAJOR == 1 | |||
#include <netif/etharp.h> | |||
#else // LWIP_VERSION_MAJOR >= 2 | |||
#include <lwip/etharp.h> | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// THERMOSTAT | |||
// ----------------------------------------------------------------------------- | |||
using thermostat_callback_f = std::function<void(bool state)>; | |||
#if THERMOSTAT_SUPPORT | |||
void thermostatRegister(thermostat_callback_f callback); | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// RTC MEMORY | |||
// ----------------------------------------------------------------------------- | |||
#include "rtcmem.h" | |||
// ----------------------------------------------------------------------------- | |||
// Warn about broken Arduino functions | |||
// ----------------------------------------------------------------------------- | |||
// Division by zero bug | |||
// https://github.com/esp8266/Arduino/pull/2397 | |||
// https://github.com/esp8266/Arduino/pull/2408 | |||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) | |||
long __attribute__((deprecated("Please avoid using map() with Core 2.3.0"))) map(long x, long in_min, long in_max, long out_min, long out_max); | |||
#endif | |||
// ----------------------------------------------------------------------------- | |||
// std::make_unique backport for C++11 | |||
// ----------------------------------------------------------------------------- | |||
#if 201103L >= __cplusplus | |||
namespace std { | |||
template<typename T, typename... Args> | |||
std::unique_ptr<T> make_unique(Args&&... args) { | |||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | |||
} | |||
} | |||
#endif |
@ -0,0 +1,48 @@ | |||
// ----------------------------------------------------------------------------- | |||
// Save crash info | |||
// Taken from krzychb EspSaveCrash | |||
// https://github.com/krzychb/EspSaveCrash | |||
// ----------------------------------------------------------------------------- | |||
#pragma once | |||
#define SAVE_CRASH_EEPROM_OFFSET 0x0100 // initial address for crash data | |||
/** | |||
* Structure of the single crash data set | |||
* | |||
* 1. Crash time | |||
* 2. Restart reason | |||
* 3. Exception cause | |||
* 4. epc1 | |||
* 5. epc2 | |||
* 6. epc3 | |||
* 7. excvaddr | |||
* 8. depc | |||
* 9. adress of stack start | |||
* 10. adress of stack end | |||
* 11. stack trace size | |||
* 12. stack trace bytes | |||
* ... | |||
*/ | |||
#define SAVE_CRASH_CRASH_TIME 0x00 // 4 bytes | |||
#define SAVE_CRASH_RESTART_REASON 0x04 // 1 byte | |||
#define SAVE_CRASH_EXCEPTION_CAUSE 0x05 // 1 byte | |||
#define SAVE_CRASH_EPC1 0x06 // 4 bytes | |||
#define SAVE_CRASH_EPC2 0x0A // 4 bytes | |||
#define SAVE_CRASH_EPC3 0x0E // 4 bytes | |||
#define SAVE_CRASH_EXCVADDR 0x12 // 4 bytes | |||
#define SAVE_CRASH_DEPC 0x16 // 4 bytes | |||
#define SAVE_CRASH_STACK_START 0x1A // 4 bytes | |||
#define SAVE_CRASH_STACK_END 0x1E // 4 bytes | |||
#define SAVE_CRASH_STACK_SIZE 0x22 // 2 bytes | |||
#define SAVE_CRASH_STACK_TRACE 0x24 // variable | |||
constexpr size_t crashUsedSpace() { | |||
return (SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_STACK_SIZE + 2); | |||
} | |||
void crashClear(); | |||
void crashDump(); | |||
void crashSetup(); |
@ -0,0 +1,28 @@ | |||
/* | |||
DOMOTICZ MODULE | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#if DOMOTICZ_SUPPORT | |||
#include <ArduinoJson.h> | |||
#include <bitset> | |||
template<typename T> | |||
void domoticzSend(const char * key, T value); | |||
template<typename T> | |||
void domoticzSend(const char * key, T nvalue, const char * svalue); | |||
void domoticzSendRelay(unsigned char relayID, bool status); | |||
void domoticzSendRelays(); | |||
void domoticzSetup(); | |||
bool domoticzEnabled(); | |||
#endif // DOMOTICZ_SUPPORT == 1 |
@ -0,0 +1,15 @@ | |||
/* | |||
GPIO MODULE | |||
Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
bool gpioValid(unsigned char gpio); | |||
bool gpioGetLock(unsigned char gpio); | |||
bool gpioReleaseLock(unsigned char gpio); | |||
void gpioSetup(); |
@ -0,0 +1,19 @@ | |||
/* | |||
HOME ASSISTANT MODULE | |||
Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#if HOMEASSISTANT_SUPPORT | |||
#include <ArduinoJson.h> | |||
struct ha_config_t; | |||
void haSetup(); | |||
#endif // HOMEASSISTANT_SUPPORT == 1 |
@ -0,0 +1,42 @@ | |||
/* | |||
I2C MODULE | |||
Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#if I2C_SUPPORT | |||
#if I2C_USE_BRZO | |||
#include <brzo_i2c.h> | |||
#else | |||
#include <Wire.h> | |||
#endif | |||
void i2c_wakeup(uint8_t address); | |||
uint8_t i2c_write_buffer(uint8_t address, uint8_t * buffer, size_t len); | |||
uint8_t i2c_write_uint8(uint8_t address, uint8_t value); | |||
uint8_t i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value); | |||
uint8_t i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value1, uint8_t value2); | |||
uint8_t i2c_write_uint16(uint8_t address, uint16_t value); | |||
uint8_t i2c_write_uint16(uint8_t address, uint8_t reg, uint16_t value); | |||
uint8_t i2c_read_uint8(uint8_t address); | |||
uint8_t i2c_read_uint8(uint8_t address, uint8_t reg); | |||
uint16_t i2c_read_uint16(uint8_t address); | |||
uint16_t i2c_read_uint16(uint8_t address, uint8_t reg); | |||
uint16_t i2c_read_uint16_le(uint8_t address, uint8_t reg); | |||
int16_t i2c_read_int16(uint8_t address, uint8_t reg); | |||
int16_t i2c_read_int16_le(uint8_t address, uint8_t reg); | |||
void i2c_read_buffer(uint8_t address, uint8_t * buffer, size_t len); | |||
void i2cScan(); | |||
void i2cClearBus(); | |||
bool i2cGetLock(unsigned char address); | |||
bool i2cReleaseLock(unsigned char address); | |||
unsigned char i2cFindAndLock(size_t size, unsigned char * addresses); | |||
#endif // I2C_SUPPORT == 1 |
@ -0,0 +1,21 @@ | |||
/* | |||
IR MODULE | |||
Copyright (C) 2018 by Alexander Kolesnikov (raw and MQTT implementation) | |||
Copyright (C) 2017-2019 by François Déchery | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#if IR_SUPPORT | |||
#include <IRremoteESP8266.h> | |||
#include <IRrecv.h> | |||
#include <IRsend.h> | |||
void irSetup(); | |||
#endif // IR_SUPPORT == 1 |
@ -0,0 +1,54 @@ | |||
/* | |||
MQTT MODULE | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
Updated secure client support by Niek van der Maas < mail at niekvandermaas dot nl> | |||
*/ | |||
#pragma once | |||
#include <WString.h> | |||
#include <utility> | |||
#include <functional> | |||
using mqtt_callback_f = std::function<void(unsigned int type, const char * topic, char * payload)>; | |||
using mqtt_msg_t = std::pair<String, String>; // topic, payload | |||
#if MQTT_SUPPORT | |||
#if MQTT_LIBRARY == MQTT_LIBRARY_ASYNCMQTTCLIENT | |||
#include <ESPAsyncTCP.h> | |||
#include <AsyncMqttClient.h> | |||
#elif MQTT_LIBRARY == MQTT_LIBRARY_ARDUINOMQTT | |||
#include <MQTTClient.h> | |||
#elif MQTT_LIBRARY == MQTT_LIBRARY_PUBSUBCLIENT | |||
#include <PubSubClient.h> | |||
#endif | |||
void mqttRegister(mqtt_callback_f callback); | |||
String mqttTopic(const char * magnitude, bool is_set); | |||
String mqttTopic(const char * magnitude, unsigned int index, bool is_set); | |||
String mqttMagnitude(char * topic); | |||
bool mqttSendRaw(const char * topic, const char * message, bool retain); | |||
bool mqttSendRaw(const char * topic, const char * message); | |||
void mqttSend(const char * topic, const char * message, bool force, bool retain); | |||
void mqttSend(const char * topic, const char * message, bool force); | |||
void mqttSend(const char * topic, const char * message); | |||
void mqttSend(const char * topic, unsigned int index, const char * message, bool force); | |||
void mqttSend(const char * topic, unsigned int index, const char * message); | |||
const String& mqttPayloadOnline(); | |||
const String& mqttPayloadOffline(); | |||
const char* mqttPayloadStatus(bool status); | |||
void mqttSendStatus(); | |||
#endif // MQTT_SUPPORT == 1 |
@ -1,79 +1,44 @@ | |||
/* | |||
OTA COMMON FUNCTIONS | |||
OTA MODULE | |||
*/ | |||
#pragma once | |||
#include "ws.h" | |||
#include <Updater.h> | |||
void otaPrintError() { | |||
if (Update.hasError()) { | |||
#if TERMINAL_SUPPORT | |||
Update.printError(terminalSerial()); | |||
#elif DEBUG_SERIAL_SUPPORT && defined(DEBUG_PORT) | |||
Update.printError(DEBUG_PORT); | |||
#endif | |||
} | |||
} | |||
bool otaFinalize(size_t size, int reason, bool evenIfRemaining = false) { | |||
if (Update.isRunning() && Update.end(evenIfRemaining)) { | |||
DEBUG_MSG_P(PSTR("[OTA] Success: %7u bytes\n"), size); | |||
deferredReset(500, reason); | |||
return true; | |||
} | |||
otaPrintError(); | |||
eepromRotate(true); | |||
return false; | |||
} | |||
#if OTA_ARDUINOOTA_SUPPORT | |||
#include <ArduinoOTA.h> | |||
void arduinoOtaSetup(); | |||
#endif // OTA_ARDUINOOTA_SUPPORT == 1 | |||
#if OTA_CLIENT == OTA_CLIENT_ASYNCTCP | |||
#include <ESPAsyncTCP.h> | |||
void otaClientSetup(); | |||
#endif // OTA_CLIENT == OTA_CLIENT_ASYNCTCP | |||
#if OTA_CLIENT == OTA_CLIENT_HTTPUPDATE | |||
#include <ESP8266HTTPClient.h> | |||
#include <ESP8266httpUpdate.h> | |||
void otaClientSetup(); | |||
#endif // OTA_CLIENT == OTA_CLIENT_HTTPUPDATE | |||
#if SECURE_CLIENT != SECURE_CLIENT_NONE | |||
#include <WiFiClientSecure.h> | |||
#endif | |||
void otaPrintError(); | |||
bool otaFinalize(size_t size, int reason, bool evenIfRemaining = false); | |||
// Helper methods from UpdaterClass that need to be called manually for async mode, | |||
// because we are not using Stream interface to feed it data. | |||
bool otaVerifyHeader(uint8_t* data, size_t len) { | |||
if (len < 4) { | |||
return false; | |||
} | |||
// ref: https://github.com/esp8266/Arduino/pull/6820 | |||
// accept gzip, let unpacker figure things out later | |||
if (data[0] == 0x1F && data[1] == 0x8B) { | |||
return true; | |||
} | |||
// Check for magic byte with a normal .bin | |||
if (data[0] != 0xE9) { | |||
return false; | |||
} | |||
// Make sure that flash config can be recognized and fit the flash | |||
const auto flash_config = ESP.magicFlashChipSize((data[3] & 0xf0) >> 4); | |||
if (flash_config && (flash_config > ESP.getFlashChipRealSize())) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
void otaProgress(size_t bytes, size_t each = 8192u) { | |||
// Removed to avoid websocket ping back during upgrade (see #1574) | |||
// TODO: implement as separate from debugging message | |||
#if WEB_SUPPORT | |||
if (wsConnected()) return; | |||
#endif | |||
// Telnet and serial will still output things, but slightly throttled | |||
static size_t last = 0; | |||
if (bytes < last) { | |||
last = 0; | |||
} | |||
if ((bytes > each) && (bytes - each > last)) { | |||
DEBUG_MSG_P(PSTR("[OTA] Progress: %7u bytes\r"), bytes); | |||
last = bytes; | |||
} | |||
} | |||
bool otaVerifyHeader(uint8_t* data, size_t len); | |||
void otaProgress(size_t bytes, size_t each = 8192u); |
@ -0,0 +1,79 @@ | |||
/* | |||
OTA MODULE COMMON FUNCTIONS | |||
*/ | |||
#include "ota.h" | |||
#include "system.h" | |||
#include "terminal.h" | |||
#include "ws.h" | |||
void otaPrintError() { | |||
if (Update.hasError()) { | |||
#if TERMINAL_SUPPORT | |||
Update.printError(terminalSerial()); | |||
#elif DEBUG_SERIAL_SUPPORT && defined(DEBUG_PORT) | |||
Update.printError(DEBUG_PORT); | |||
#endif | |||
} | |||
} | |||
bool otaFinalize(size_t size, int reason, bool evenIfRemaining) { | |||
if (Update.isRunning() && Update.end(evenIfRemaining)) { | |||
DEBUG_MSG_P(PSTR("[OTA] Success: %7u bytes\n"), size); | |||
deferredReset(500, reason); | |||
return true; | |||
} | |||
otaPrintError(); | |||
eepromRotate(true); | |||
return false; | |||
} | |||
// Helper methods from UpdaterClass that need to be called manually for async mode, | |||
// because we are not using Stream interface to feed it data. | |||
bool otaVerifyHeader(uint8_t* data, size_t len) { | |||
if (len < 4) { | |||
return false; | |||
} | |||
// ref: https://github.com/esp8266/Arduino/pull/6820 | |||
// accept gzip, let unpacker figure things out later | |||
if (data[0] == 0x1F && data[1] == 0x8B) { | |||
return true; | |||
} | |||
// Check for magic byte with a normal .bin | |||
if (data[0] != 0xE9) { | |||
return false; | |||
} | |||
// Make sure that flash config can be recognized and fit the flash | |||
const auto flash_config = ESP.magicFlashChipSize((data[3] & 0xf0) >> 4); | |||
if (flash_config && (flash_config > ESP.getFlashChipRealSize())) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
void otaProgress(size_t bytes, size_t each) { | |||
// Removed to avoid websocket ping back during upgrade (see #1574) | |||
// TODO: implement as separate from debugging message | |||
#if WEB_SUPPORT | |||
if (wsConnected()) return; | |||
#endif | |||
// Telnet and serial will still output things, but slightly throttled | |||
static size_t last = 0; | |||
if (bytes < last) { | |||
last = 0; | |||
} | |||
if ((bytes > each) && (bytes - each > last)) { | |||
DEBUG_MSG_P(PSTR("[OTA] Progress: %7u bytes\r"), bytes); | |||
last = bytes; | |||
} | |||
} |
@ -0,0 +1,24 @@ | |||
/* | |||
RF BRIDGE MODULE | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#if RF_SUPPORT | |||
#if RFB_DIRECT | |||
#include <RCSwitch.h> | |||
#endif | |||
void rfbStatus(unsigned char id, bool status); | |||
void rfbLearn(unsigned char id, bool status); | |||
String rfbRetrieve(unsigned char id, bool status); | |||
void rfbStore(unsigned char id, bool status, const char * code); | |||
void rfbForget(unsigned char id, bool status); | |||
void rfbSetup(); | |||
#endif // RF_SUPPORT == 1 |
@ -0,0 +1,29 @@ | |||
/* | |||
RFM69 MODULE | |||
Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
struct packet_t; | |||
#if RFM69_SUPPORT | |||
#include "libs/RFM69Wrap.h" | |||
struct packet_t { | |||
unsigned long messageID; | |||
unsigned char packetID; | |||
unsigned char senderID; | |||
unsigned char targetID; | |||
char * key; | |||
char * value; | |||
int16_t rssi; | |||
}; | |||
void rfm69Setup(); | |||
#endif // RFM69_SUPPORT == 1 |
@ -0,0 +1,24 @@ | |||
/* | |||
EEPROM MODULE | |||
*/ | |||
// XXX: with case insensitive filesystem, if named eeprom.h *could* | |||
// be included as EEPROM.h and fail after including rotate library down below | |||
#pragma once | |||
#include <EEPROM_Rotate.h> | |||
extern EEPROM_Rotate EEPROMr; | |||
void eepromSectorsDebug(); | |||
void eepromRotate(bool value); | |||
uint32_t eepromCurrent(); | |||
String eepromSectors(); | |||
void eepromBackup(uint32_t index); | |||
void eepromCommit(); | |||
void eepromSetup(); |
@ -0,0 +1,21 @@ | |||
/* | |||
TERMINAL MODULE | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#if TERMINAL_SUPPORT | |||
#include "libs/EmbedisWrap.h" | |||
using embedis_command_f = void (*)(Embedis*); | |||
void terminalRegisterCommand(const String& name, embedis_command_f func); | |||
void terminalInject(void *data, size_t len); | |||
Stream& terminalSerial(); | |||
#endif // TERMINAL_SUPPORT == 1 |
@ -0,0 +1,19 @@ | |||
/* | |||
THERMOSTAT MODULE | |||
Copyright (C) 2017 by Dmitry Blinov <dblinov76 at gmail dot com> | |||
*/ | |||
#pragma once | |||
#include <ArduinoJson.h> | |||
#include <float.h> | |||
#if THERMOSTAT_DISPLAY_SUPPORT | |||
#include <SSD1306.h> // alias for `#include "SSD1306Wire.h"` | |||
#endif | |||
using thermostat_callback_f = std::function<void(bool state)>; | |||
void thermostatRegister(thermostat_callback_f callback); |
@ -0,0 +1,120 @@ | |||
// Shim original TimeLib functions | |||
#pragma once | |||
constexpr time_t daysPerWeek = 7; | |||
constexpr time_t secondsPerMinute = 60; | |||
constexpr time_t secondsPerHour = 3600; | |||
constexpr time_t secondsPerDay = secondsPerHour * 24; | |||
constexpr time_t secondsPerWeek = daysPerWeek * secondsPerDay; | |||
constexpr time_t secondsPerYear = secondsPerWeek * 52; | |||
constexpr time_t secondsY2K = 946684800; // the time at the start of y2k | |||
// wall clock values | |||
constexpr const time_t numberOfSeconds(uint32_t ts) { | |||
return (ts % secondsPerMinute); | |||
} | |||
constexpr const time_t numberOfMinutes(uint32_t ts) { | |||
return ((ts / secondsPerMinute) % secondsPerMinute); | |||
} | |||
constexpr const time_t numberOfHours(uint32_t ts) { | |||
return ((ts % secondsPerDay) / secondsPerHour); | |||
} | |||
// week starts with sunday as number 1, monday as 2 etc. | |||
constexpr const time_t dayOfWeek(time_t ts) { | |||
return ((ts / secondsPerDay + 4) % daysPerWeek) + 1; | |||
} | |||
// the number of days since 0 (Jan 1 1970 in case of time_t values) | |||
constexpr const time_t elapsedDays(uint32_t ts) { | |||
return (ts / secondsPerDay); | |||
} | |||
// the number of seconds since last midnight | |||
constexpr const time_t elapsedSecsToday(uint32_t ts) { | |||
return (ts % secondsPerDay); | |||
} | |||
// The following methods are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971 | |||
// Always set the correct time before settting alarms | |||
// time at the start of the given day | |||
constexpr const time_t previousMidnight(time_t ts) { | |||
return ((ts / secondsPerDay) * secondsPerDay); | |||
} | |||
// time at the end of the given day | |||
constexpr const time_t nextMidnight(time_t ts) { | |||
return previousMidnight(ts) + secondsPerDay; | |||
} | |||
// note that week starts on day 1 | |||
constexpr const time_t elapsedSecsThisWeek(uint32_t ts) { | |||
return elapsedSecsToday(ts) + ((dayOfWeek(ts) - 1) * secondsPerDay); | |||
} | |||
// time at the start of the week for the given time | |||
constexpr const time_t previousSunday(time_t ts) { | |||
return ts - elapsedSecsThisWeek(ts); | |||
} | |||
// time at the end of the week for the given time | |||
constexpr const time_t nextSunday(time_t ts) { | |||
return previousSunday(ts) + secondsPerWeek; | |||
} | |||
year(t), month(t), day(t), hour(t), minute(t), second(t) | |||
static time_t _ntp_ts = 0; | |||
static tm _ntp_tm; | |||
void _ntpTmCache(time_t ts) { | |||
if (_ntp_tm != ts) { | |||
_ntp_ts = ts; | |||
localtime_r(_ntp_ts, _ntp_tm); | |||
} | |||
} | |||
int hour(time_t ts) { | |||
_ntpTmCache(ts); | |||
return _ntp_tm.tm_hour; | |||
} | |||
int minute(time_t ts) { | |||
_ntpTmCache(ts); | |||
return _ntp_tm.tm_min; | |||
} | |||
int second(time_t ts) { | |||
_ntpTmCache(ts); | |||
return _ntp_tm.tm_sec; | |||
} | |||
int day(time_t ts) { | |||
_ntpTmCache(ts); | |||
return _ntp_tm.tm_day; | |||
} | |||
int weekday(time_t ts) { | |||
_ntpTmCache(ts); | |||
return _ntp_tm.tm_wday; | |||
} | |||
int month(time_t ts) { | |||
_ntpTmCache(ts); | |||
return _ntp_tm.tm_mon; | |||
} | |||
int year(time_t ts) { | |||
_ntpTmCache(ts); | |||
return _ntp_tm.tm_year; | |||
} | |||
time_t now() { | |||
return time(nullptr); | |||
} |
@ -0,0 +1,18 @@ | |||
/* | |||
UART_MQTT MODULE | |||
Copyright (C) 2018 by Albert Weterings | |||
Adapted by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#if UART_MQTT_SUPPORT | |||
#include <SoftwareSerial.h> | |||
void uartmqttSetup(); | |||
#endif // UART_MQTT_SUPPORT == 1 |
@ -0,0 +1,41 @@ | |||
/* | |||
WEBSERVER MODULE | |||
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#pragma once | |||
#include <functional> | |||
#if WEB_SUPPORT | |||
#include <ESPAsyncTCP.h> | |||
#include <ESPAsyncWebServer.h> | |||
#include <Hash.h> | |||
#include <FS.h> | |||
#include <AsyncJson.h> | |||
#include <ArduinoJson.h> | |||
#else | |||
// TODO: need these prototypes for .ino | |||
class AsyncClient; | |||
class AsyncWebServer; | |||
class AsyncWebServerRequest; | |||
class ArRequestHandlerFunction; | |||
class AsyncWebSocketClient; | |||
class AsyncWebSocket; | |||
class AwsEventType; | |||
#endif // WEB_SUPPORT == 1 | |||
using web_body_callback_f = std::function<bool(AsyncWebServerRequest*, uint8_t* data, size_t len, size_t index, size_t total)>; | |||
using web_request_callback_f = std::function<bool(AsyncWebServerRequest*)>; | |||
AsyncWebServer* webServer(); | |||
void webBodyRegister(web_body_callback_f); | |||
void webRequestRegister(web_request_callback_f); |