* 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 | #pragma once | ||||
#include "ws.h" | |||||
#include <Updater.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, | // Helper methods from UpdaterClass that need to be called manually for async mode, | ||||
// because we are not using Stream interface to feed it data. | // 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); |