diff --git a/.gitignore b/.gitignore
index a4938ce5..d656f83e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,8 +5,10 @@
.git
.pio
data/*
+src/user_setups/active/*
src/user_config_override.h
platformio_override.ini
+user_setups/active/*
## Visual Studio Code specific ######
.vscode
diff --git a/README.md b/README.md
index e9c141ba..763e189d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,10 @@
# HASP - Open Hardware edition
+
+[](https://github.com/fvanroie/hasp-lvgl/releases)
+[](https://github.com/fvanroie/hasp-lvgl/blob/master/LICENSE)
+[](#Contributing)
+[](http://github.com/fvanroie/hasp-lvgl/issues)
+
This project is a re-implementation of the popular HASwitchPlate sketch created by aderusha.
The [original HASwitchPlate][1] project uses a Wemos D1 mini and requires a Nextion/TJC HMI display.
This rewrite removes the Nextion/TJC requirement by using the [Littlev Graphics Library][2] on the MCU to drive a cheap commodity display.
@@ -19,14 +25,14 @@ This version also adds ESP32 and STM32 support to take advantage of the addition
| SPI display | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| Parallel display | :x: no | :white_check_mark: yes | :white_check_mark: yes
| PWM Screen dimming | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
-| Maximum Page Count | 4 | 12 |
+| Maximum Page Count | 4 | 12 | 12
| Object Types / Widgets | 14 | 15 | 15
| Dynamic Objects | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| [Lvgl Theme Support][3] | basic only | all themes | tbd
| [Custom .zi V5 font][4] | :white_check_mark: yes (latin1) | :white_check_mark: yes (latin1) | no
| [FontAwesome Icons][5] | :white_check_mark: 1300+ | :white_check_mark: 1300+ | no
| PNG images | :x: no | :grey_question: tbd | :grey_question: tbd
-| Network | :white_check_mark: Wifi | :white_check_mark: Wifi | :grey_question: tbd
+| Network | :white_check_mark: Wifi | :white_check_mark: Wifi | :white_check_mark: Ethernet
## Cloning
diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index a14b936f..28260cbd 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -7,43 +7,88 @@
#define HASP_USE_APP 1
-/* Network */
-#define HASP_HAS_NETWORK (ARDUINO_ARCH_ESP32>0 || ARDUINO_ARCH_ESP8266>0)
+/* Network Services */
+#define HASP_HAS_NETWORK (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0)
+#ifndef HASP_USE_OTA
#define HASP_USE_OTA (HASP_HAS_NETWORK)
-#define HASP_USE_WIFI (HASP_HAS_NETWORK)
-#define HASP_USE_MQTT (HASP_HAS_NETWORK)
-#define HASP_USE_HTTP (HASP_HAS_NETWORK)
-#define HASP_USE_MDNS (HASP_HAS_NETWORK)
-#define HASP_USE_SYSLOG (HASP_HAS_NETWORK)
-#define HASP_USE_TELNET (HASP_HAS_NETWORK)
-
-/* Filesystem */
-#define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32>0 || ARDUINO_ARCH_ESP8266>0)
-
-#define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM)
-#define HASP_USE_EEPROM (HASP_HAS_FILESYSTEM)
-#define HASP_USE_SDCARD 0
-
-#define HASP_USE_BUTTON 1
-
-#define HASP_USE_QRCODE 1
-#define HASP_USE_PNGDECODE 0
-
-#define HASP_NUM_INPUTS 3 // Buttons
-#define HASP_NUM_OUTPUTS 3
-
-#if defined(ARDUINO_ARCH_ESP32)
-#define HASP_NUM_PAGES 12
-#else
-#define HASP_NUM_PAGES 4
#endif
+#ifndef HASP_USE_WIFI
+#define HASP_USE_WIFI (HASP_HAS_NETWORK)
+#endif
-#if HASP_USE_SPIFFS>0
+#ifndef HASP_USE_ETHERNET
+#define HASP_USE_ETHERNET 0
+#endif
+
+#ifndef HASP_USE_MQTT
+#define HASP_USE_MQTT 1
+#endif
+
+#ifndef HASP_USE_HTTP
+#define HASP_USE_HTTP 1
+#endif
+
+#ifndef HASP_USE_MDNS
+#define HASP_USE_MDNS (HASP_HAS_NETWORK)
+#endif
+
+#ifndef HASP_USE_SYSLOG
+#define HASP_USE_SYSLOG 0
+#endif
+
+#ifndef HASP_USE_TELNET
+#define HASP_USE_TELNET 0
+#endif
+
+/* Filesystem */
+#define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0)
+
+#ifndef HASP_USE_SPIFFS
+#define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM)
+#endif
+
+#ifndef HASP_USE_EEPROM
+#define HASP_USE_EEPROM 1
+#endif
+
+#ifndef HASP_USE_SDCARD
+#define HASP_USE_SDCARD 0
+#endif
+
+#ifndef HASP_USE_GPIO
+#define HASP_USE_GPIO 1
+#endif
+
+#ifndef HASP_USE_QRCODE
+#define HASP_USE_QRCODE 1
+#endif
+
+#ifndef HASP_USE_PNGDECODE
+#define HASP_USE_PNGDECODE 0
+#endif
+
+#ifndef HASP_NUM_INPUTS
+#define HASP_NUM_INPUTS 3 // Buttons
+#endif
+
+#ifndef HASP_NUM_OUTPUTS
+#define HASP_NUM_OUTPUTS 3
+#endif
+
+#ifndef HASP_NUM_PAGES
+#if defined(ARDUINO_ARCH_ESP8266)
+#define HASP_NUM_PAGES 4
+#else
+#define HASP_NUM_PAGES 12
+#endif
+#endif
+
+/* Includes */
+#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
-#include "hasp_eeprom.h"
#endif
#include // Include the SPIFFS library
#include "hasp_spiffs.h"
@@ -51,42 +96,70 @@
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
//#include "lv_zifont.h"
#endif
-#endif
+#endif // SPIFFS
-#if HASP_USE_EEPROM>0
+#if HASP_USE_EEPROM > 0
#include "hasp_eeprom.h"
#endif
-#if HASP_USE_WIFI>0
+#if HASP_USE_WIFI > 0
#include "hasp_wifi.h"
#endif
-#if HASP_USE_MQTT>0
+#if HASP_USE_ETHERNET > 0
+#if USE_BUILTIN_ETHERNET > 0
+#include
+#include
+#warning Use built-in STM32 Ethernet
+#elif USE_UIP_ETHERNET
+#include
+#include
+#warning Use ENC28J60 Ethernet shield
+#else
+#include "Ethernet.h"
+#warning Use W5x00 Ethernet shield
+#endif
+#include "hasp_ethernet.h"
+#endif
+
+#if HASP_USE_MQTT > 0
#include "hasp_mqtt.h"
#endif
-#if HASP_USE_HTTP>0
+#if HASP_USE_HTTP > 0
#include "hasp_http.h"
#endif
-#if HASP_USE_TELNET>0
+#if HASP_USE_TELNET > 0
#include "hasp_telnet.h"
#endif
-#if HASP_USE_MDNS>0
+#if HASP_USE_MDNS > 0
#include "hasp_mdns.h"
#endif
-#if HASP_USE_BUTTON>0
+#if HASP_USE_BUTTON > 0
#include "hasp_button.h"
#endif
-#if HASP_USE_OTA>0
+#if HASP_USE_OTA > 0
#include "hasp_ota.h"
#endif
+#if HASP_USE_TASMOTA_SLAVE > 0
+#include "hasp_slave.h"
+#endif
+
+#if HASP_USE_ETHERNET > 0
+#include "hasp_ethernet.h"
#endif
#ifndef FPSTR
#define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
#endif
+
+#ifndef PGM_P
+#define PGM_P const char *
+#endif
+
+#endif // HASP_CONF_H
\ No newline at end of file
diff --git a/include/lv_conf.h b/include/lv_conf.h
index 244aa61a..85829f49 100644
--- a/include/lv_conf.h
+++ b/include/lv_conf.h
@@ -80,7 +80,7 @@ typedef int16_t lv_coord_t;
# define LV_MEM_SIZE (12 * 1024U) // 12KB
#endif
#ifndef LV_MEM_SIZE
-# define LV_MEM_SIZE (64 * 1024U) // 48KB
+# define LV_MEM_SIZE (20 * 1024U) // 48KB
#endif
/* Complier prefix for a big array declaration */
diff --git a/include/stm32f4/hal_conf_custom.h b/include/stm32f4/hal_conf_custom.h
new file mode 100644
index 00000000..b0bc4acf
--- /dev/null
+++ b/include/stm32f4/hal_conf_custom.h
@@ -0,0 +1,16 @@
+/* Include the normal default core configuration */
+#include "stm32f4xx_hal_conf_default.h"
+
+#if USE_BUILTIN_ETHERNET
+/* Remove the default PHY address */
+#ifdef LAN8742A_PHY_ADDRESS
+#undef LAN8742A_PHY_ADDRESS
+#endif
+
+/* Section 2: PHY configuration section */
+/* Redefine LAN8742A PHY Address*/
+#ifndef LAN8742A_PHY_ADDRESS
+#define LAN8742A_PHY_ADDRESS 0x01U //HASP_PHY_ADDRESS
+#endif
+
+#endif
\ No newline at end of file
diff --git a/lcd_config.ini b/lcd_config.ini
index 0e421971..dcbd3ebb 100644
--- a/lcd_config.ini
+++ b/lcd_config.ini
@@ -8,7 +8,7 @@ lolin24 =
-D ILI9341_DRIVER=1
-D TFT_WIDTH=240
-D TFT_HEIGHT=320
- -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
+ -D TFT_ROTATION=2 ; 0=0, 1=90, 2=180 or 3=270 degree
-D SPI_FREQUENCY=40000000
-D SPI_TOUCH_FREQUENCY=2500000
-D SPI_READ_FREQUENCY=20000000
diff --git a/lib/ArduinoLog/ArduinoLog.cpp b/lib/ArduinoLog/ArduinoLog.cpp
index d9ad7e06..c7265fd0 100644
--- a/lib/ArduinoLog/ArduinoLog.cpp
+++ b/lib/ArduinoLog/ArduinoLog.cpp
@@ -129,7 +129,6 @@ void Logging::print(Print * logOutput, const char * format, va_list args)
++format;
printFormat(logOutput, *format, (va_list *)&args);
} else {
- //_logOutput->print(*format);
logOutput->print(*format);
}
}
diff --git a/lib/ArduinoLog/ArduinoLog.h b/lib/ArduinoLog/ArduinoLog.h
index 645d4f74..d0f9f3d9 100644
--- a/lib/ArduinoLog/ArduinoLog.h
+++ b/lib/ArduinoLog/ArduinoLog.h
@@ -285,19 +285,15 @@ class Logging {
if(_logOutput[i] == NULL || level>_level[i]) continue;
if(_prefix != NULL) {
- // _prefix(level, _logOutput[i]);
+ _prefix(level, _logOutput[i]);
}
va_list args;
va_start(args, msg);
-#ifdef STM32_CORE_VERSION_MAJOR
- print(_logOutput[i], msg, args);
- Serial.println();
-#else
- print(_logOutput[i], msg, args);
-#endif
+ print(_logOutput[i], msg, args);
+
if(_suffix != NULL) {
- // _suffix(level, _logOutput[i]);
+ _suffix(level, _logOutput[i]);
}
}
diff --git a/lib/lv_fs_if/lv_fs_spiffs.cpp b/lib/lv_fs_if/lv_fs_spiffs.cpp
index 49acb1ce..aad335bd 100644
--- a/lib/lv_fs_if/lv_fs_spiffs.cpp
+++ b/lib/lv_fs_if/lv_fs_spiffs.cpp
@@ -150,7 +150,7 @@ static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path,
Log.verbose(F("LVFS: %d"), __LINE__);
lv_spiffs_file_t * fp = (lv_spiffs_file_t *)file_p; /*Just avoid the confusing casings*/
// Log.verbose(F("LVFS: Copying %s"), f.name());
- Log.verbose(F("LVFS: %d"), __LINE__);
+ Log.verbose(F("LVFS: %d - %x - %d"), __LINE__, fp, sizeof(lv_spiffs_file_t));
if (fp != NULL) (*fp) = file;
// memcpy(fp,&file,sizeof(lv_spiffs_file_t));
Log.verbose(F("LVFS: %d"), __LINE__);
diff --git a/lib/lvgl b/lib/lvgl
index 8b663bdc..ecd0d4fb 160000
--- a/lib/lvgl
+++ b/lib/lvgl
@@ -1 +1 @@
-Subproject commit 8b663bdc39b8a745cee39334b2f6c065babd5fd9
+Subproject commit ecd0d4fb0907d73e07788283c16e5a4ab1e829b6
diff --git a/platformio.ini b/platformio.ini
index 81b7f8d9..8a971a18 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -18,6 +18,9 @@ extra_configs =
pin_config.ini
; -- Add customizations to this file only:
platformio_override.ini
+ ; -- Put active [env] files in this dir to be included in the build menu
+ user_setups/active/*.ini
+ user_setups/*/*.ini
default_envs =
; Uncomment the needed environments in platformio_override.ini
@@ -47,11 +50,13 @@ lib_deps =
;TFT_eSPI@^1.4.20 ; Tft SPI drivers
PubSubClient@^2.7.0 ; MQTT client
ArduinoJson@^6.15.1,>6.15.0 ; needs at least 6.15.0
+ StreamUtils@^1.4.0
Syslog@^2.0.0
AceButton@^1.4.0
;AsyncTCP
;https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip
;https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip
+ https://github.com/andrethomas/TasmotaSlave.git
lib_ignore =
https://github.com/littlevgl/lvgl.git
@@ -67,6 +72,7 @@ build_flags =
-D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files
-D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols
-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments
+ -D STREAMUTILS_ENABLE_EEPROM=1 ; for STM32, it also supports EEPROM
;-D DISABLE_LOGGING
-I include ; include lv_conf.h and hasp_conf.h
${override.build_flags}
@@ -88,6 +94,9 @@ esp32_flags=
stm32_flags=
${env.build_flags}
-D IRAM_ATTR= ; No IRAM_ATTR available on STM32
+ -D STM32
+ -D STREAMUTILS_USE_EEPROM_UPDATE=1 ; update cell only when changed
+ -D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
; -- By default there are no ${override.build_flags} set
; -- to use it, copy platformio_override.ini from the template
@@ -120,210 +129,6 @@ hspi32 =
; 7 - mirror content, and rotate 90 deg anti-clockwise
-
-;***************************************************
-; STM32F4 build
-;***************************************************
-[env:black_f407vg]
-platform = ststm32
-board = diymore_f407vgt
-board_build.mcu = stm32f407vgt6
-upload_protocol = dfu
-monitor_port = COM7 ; To change the port, use platform_override.ini
-build_flags =
- ${env.build_flags}
- ${flags.stm32_flags}
- -I include/stm32f4
-; -- TFT_eSPI build options ------------------------
- ${lcd.lolin24}
- ;-D TFT_MISO=PB4 ;Default
- ;-D TFT_MOSI=PB5 ;Default
- ;-D TFT_SCLK=PB3 ;Default
- -D TFT_CS=PB11 ;D8
- -D TFT_DC=PC5 ;D3
- -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
- -D TOUCH_CS=PC4 ;NC
- -D TFT_RST=-1 ;D4
- -D STM32
-
-lib_deps =
- ${env.lib_deps}
- Ticker@^3.1.5
- STM32duino LwIP@^2.1.2
- STM32duino STM32Ethernet@^1.0.5
-
-src_filter = +<*> -<.git/> -<.svn/> - - - - - +
-
-
-;***************************************************
-; Generic ESP32 build
-;***************************************************
-[env:esp32dev-mrb3511]
-platform = espressif32
-board = esp32dev
-upload_port = COM1 ; To change the port, use platform_override.ini
-monitor_port = COM1 ; To change the port, use platform_override.ini
-debug_tool = esp-prog
-debug_init_break = tbreak setup
-
-build_flags =
- ${flags.esp32_flags}
-; -- TFT_eSPI build options ------------------------
- ${lcd.mrb3511}
- -D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
- -D TFT_CS=33 ; Chip select control pin
- -D TFT_DC=15 ; =RS; Data Command control pin - must use a pin in the range 0-31
- -D TFT_RST=32 ; Reset pin
- -D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
- -D TFT_RD=2
- -D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
- -D TFT_D1=13 ; so a single register write sets/clears all bits
- -D TFT_D2=26
- -D TFT_D3=25
- -D TFT_D4=17
- -D TFT_D5=16
- -D TFT_D6=27
- -D TFT_D7=14
- -D TOUCH_SDA=21
- -D TOUCH_SCL=22
- -D TOUCH_IRQ=34 ; use 34-39 as these are input only pins
- -D TOUCH_RST=-1 ; not used, connected to 3.3V
-; -- Debugging options -----------------------------
-; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-
-; -- Library options -------------------------------
-lib_deps =
- ${env.lib_deps}
- https://github.com/netwizeBE/arduino-goodix.git ; GT911 touch screen driver
-
-src_filter = +<*> +<../drivers/stm32f429_disco>
-
-
-;***************************************************
-; Generic ESP32 build with ILI9488 SPI 4-WIRE
-;***************************************************
-[env:esp32dev-ili9488]
-platform = espressif32
-board = esp32dev
-upload_port = COM2 ; To change the port, use platform_override.ini
-monitor_port = COM2 ; To change the port, use platform_override.ini
-; upload_protocol = espota ; Use ArduinoOTA after flashing over serial
-; upload_port = 10.4.0.171 ; IP of the ESP
-; upload_flags =
-; --port=3232
-debug_tool = esp-prog
-debug_init_break = tbreak setup
-
-build_flags =
- ${flags.esp32_flags}
-; -- TFT_eSPI build options ------------------------
- -D USER_SETUP_LOADED=1
- -D ILI9488_DRIVER=1
- -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
- -D TFT_WIDTH=320
- -D TFT_HEIGHT=480
- -D TFT_MISO=19 ;// (leave TFT SDO disconnected if other SPI devices share MISO)
- -D TFT_MOSI=23
- -D TFT_SCLK=18
- -D TFT_CS=15 ;// Chip select control pin
- -D TFT_DC=2 ;// Data Command control pin
- -D TFT_RST=4 ;// Reset pin (could connect to RST pin)
- -D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
- -D SUPPORT_TRANSACTIONS
- -D TOUCH_CS=22
- -D TOUCH_DRIVER=0 ; XPT2606 Resistive touch panel driver
- -D SPI_FREQUENCY=27000000
- -D SPI_TOUCH_FREQUENCY=2500000
- -D SPI_READ_FREQUENCY=16000000
-
-; -- Debugging options -----------------------------
-; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-
-; -- Library options -------------------------------
-lib_deps =
- ${env.lib_deps}
-
-src_filter = +<*> +<../drivers/stm32f429_disco>
-
-
-;***************************************************
-; NodeMCU32S with MHS-4" RPI Display-B
-;***************************************************
-[env:nodemcu32s-raspi]
-platform = espressif32
-board = nodemcu-32s
-upload_port = COM3 ; To change the port, use platform_override.ini
-monitor_port = COM3 ; To change the port, use platform_override.ini
-debug_tool = esp-prog
-debug_init_break = tbreak setup
-
-build_flags =
- ${flags.esp32_flags}
-; -- TFT_eSPI build options ------------------------
- ${lcd.raspberrypi}
- ${pins.vspi32}
- -D TFT_CS=15
- -D TFT_DC=4
- -D TFT_RST=32
- -D TOUCH_CS=22
-
-; -- Debugging options -----------------------------
-; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-
-; -- Library options -------------------------------
-lib_deps =
- ${env.lib_deps}
-
-
-;***************************************************
-; ESP32 build
-;***************************************************
-[env:d132-unoshield]
-platform = espressif32
-board = esp32dev
-upload_port = COM4 ; To change the port, use platform_override.ini
-monitor_port = COM4 ; To change the port, use platform_override.ini
-
-build_flags =
- ${flags.esp32_flags}
-; -- TFT_eSPI build options ------------------------
- -D USER_SETUP_LOADED=1
- ;-D ST7796_DRIVER=1 ;3.95inch Arduino Display-UNO
- -D ILI9486_DRIVER=1 ;3.5inch Arduino Display-UNO
- -D ESP32_PARALLEL=1
- -D TFT_ROTATION=${lcd.TFT_ROTATION}
- -D TFT_WIDTH=320
- -D TFT_HEIGHT=480
- ${pins.vspi32}
- -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
- -D TFT_CS=33 ; Chip select control pin
- -D TFT_DC=15 ; Data Command control pin - must use a pin in the range 0-31
- -D TFT_RST=32 ; Reset pin
- -D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
- -D TFT_RD=2
- -D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
- -D TFT_D1=13 ; so a single register write sets/clears all bits
- -D TFT_D2=26
- -D TFT_D3=25
- -D TFT_D4=17
- -D TFT_D5=16
- -D TFT_D6=27
- -D TFT_D7=14
- -D SD_CS=5
- -D SPI_FREQUENCY=40000000
- ;-D SPI_TOUCH_FREQUENCY=2500000 ; Uses ADC instead
- -D SPI_READ_FREQUENCY=20000000
-; -- Debugging options -----------------------------
-; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-
-; -- Library options -------------------------------
-lib_deps =
- ${env.lib_deps}
-
-src_filter = +<*> +<../drivers/stm32f429_disco>
-
-
-
;***************************************************
; D1 Mini ESP32 with Lolin TFT 2.4"
;***************************************************
@@ -393,42 +198,6 @@ build_flags =
-D TFT_RST=-1 ;RST
-;***************************************************
-; ESP-12 build
-;***************************************************
-[env:esp12e-st7735]
-platform = espressif8266@^2.4.0 ;@2.3.2
-board = esp12e
-upload_port = COM8 ; To change the port, use platform_override.ini
-monitor_port = COM8 ; To change the port, use platform_override.ini
-board_build.f_flash = 40000000L
-board_build.flash_mode = dout
-board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs
-board_build.f_cpu = 160000000L ; set frequency to 160MHz
-build_flags =
- ${flags.esp8266_flags}
-; -- TFT_eSPI build options ------------------------
- -D USER_SETUP_LOADED=1
- -D ST7735_DRIVER=1
- -D ST7735_BLACKTAB=1
- -D TFT_ROTATION=${lcd.TFT_ROTATION}
- -D TFT_WIDTH=128
- -D TFT_HEIGHT=160
- -D TFT_MISO=-1 ;NC
- -D TFT_MOSI=13 ;D7
- -D TFT_SCLK=14 ;D5
- -D TFT_CS=15 ;D8
- -D TFT_DC=0 ;D3
- -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
- -D TOUCH_CS=-1 ;NC
- -D TFT_RST=2 ;D4
- -D SPI_FREQUENCY=27000000
-
-; -- Library options -------------------------------
-lib_deps =
- ${env.lib_deps}
- ;Ethernet@<2.0.0
-
;***************************************************
; Native build
;***************************************************
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index 85445451..92f106ae 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -1,7 +1,7 @@
-; Copy this file and rename it to platform_override.ini
-; ONLY edit platform_override.ini to make local changes to the parameters
+; Copy this file and rename it to platformio_override.ini
+; ONLY edit platformio_override.ini to make local changes to the parameters
;
-; The platform_override.ini file is not overwritten or monitored by git
+; The platformio_override.ini file is not overwritten or monitored by git
[override]
diff --git a/src/hasp.cpp b/src/hasp.cpp
index cab2eaeb..fc983b0c 100644
--- a/src/hasp.cpp
+++ b/src/hasp.cpp
@@ -3,8 +3,9 @@
*********************/
#include "hasp_conf.h"
#include
-#include "ArduinoJson.h"
#include "ArduinoLog.h"
+#include "ArduinoJson.h"
+#include "StreamUtils.h"
#include "lvgl.h"
#include "lv_conf.h"
@@ -24,6 +25,8 @@
#include "hasp_attribute.h"
#include "hasp.h"
+#include "EEPROM.h"
+
//#if LV_USE_HASP
/*********************
@@ -665,7 +668,7 @@ void haspClearPage(uint16_t pageid)
Log.warning(F("HASP: Cannot clear a layer"));
} else {
Log.notice(F("HASP: Clearing page %u"), pageid);
- lv_page_clean(pages[pageid]);
+ lv_obj_clean(pages[pageid]);
}
}
@@ -955,6 +958,15 @@ void haspLoadPage(const char * pages)
file.close();
Log.notice(F("HASP: File %s loaded"), pages);
+#else
+
+#if HASP_USE_EEPROM > 0
+ Log.notice(F("HASP: Loading jsonl from EEPROM..."));
+ EepromStream eepromStream(4096, 1024);
+ dispatchJsonl(eepromStream);
+ Log.notice(F("HASP: Loaded jsonl from EEPROM"));
+#endif
+
#endif
}
diff --git a/src/hasp.h b/src/hasp.h
index c9dbbab9..74d7a40d 100644
--- a/src/hasp.h
+++ b/src/hasp.h
@@ -19,7 +19,7 @@ extern "C" {
* INCLUDES
*********************/
-#if HASP_USE_APP
+#if HASP_USE_APP>0
/*********************
* DEFINES
@@ -81,8 +81,6 @@ void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t
void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color);
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload);
-void haspSendCmd(String nextionCmd);
-void haspParseJson(String & strPayload);
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id);
void haspReconnect(void);
@@ -101,10 +99,10 @@ void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event);
* MACROS
**********************/
-#endif /*LV_USE_DEMO*/
+#endif /*HASP_USE_APP*/
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif /*DEMO_H*/
+#endif /*HASP_H*/
diff --git a/src/hasp_attribute.cpp b/src/hasp_attribute.cpp
index 43a7aa6f..4a110d65 100644
--- a/src/hasp_attribute.cpp
+++ b/src/hasp_attribute.cpp
@@ -84,13 +84,6 @@ static lv_color_t haspPayloadToColor(const char * payload)
case 7:
if(!strcmp_P(payload, PSTR("magenta"))) return haspLogColor(LV_COLOR_MAGENTA);
- /* HEX format #rrggbb or #rrggbbaa */
- int r, g, b, a;
- if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x%2x", &r, &g, &b, &a) == 4) {
- return haspLogColor(LV_COLOR_MAKE(r, g, b));
- } else if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x", &r, &g, &b) == 3) {
- return haspLogColor(LV_COLOR_MAKE(r, g, b));
- }
default:
// if(!strcmp_P(payload, PSTR("darkblue"))) return haspLogColor(LV_COLOR_MAKE(0, 51, 102));
// if(!strcmp_P(payload, PSTR("lightblue"))) return haspLogColor(LV_COLOR_MAKE(46, 203,
@@ -98,6 +91,14 @@ static lv_color_t haspPayloadToColor(const char * payload)
break;
}
+ /* HEX format #rrggbb or #rrggbbaa */
+ int r, g, b, a;
+ if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x%2x", &r, &g, &b, &a) == 4) {
+ return haspLogColor(LV_COLOR_MAKE(r, g, b));
+ } else if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x", &r, &g, &b) == 3) {
+ return haspLogColor(LV_COLOR_MAKE(r, g, b));
+ }
+
/* 16-bit RGB565 Color Scheme*/
if(only_digits(payload)) {
uint16_t c = atoi(payload);
@@ -582,23 +583,19 @@ static void hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, co
lv_dropdown_set_selected(obj, val);
return;
} else if(check_obj_type(objtype, LV_HASP_LMETER)) {
- lv_linemeter_set_value(obj, intval);
- return;
+ return update ? lv_linemeter_set_value(obj, intval) : hasp_out_int(obj, attr, lv_linemeter_get_value(obj));
} else if(check_obj_type(objtype, LV_HASP_SLIDER)) {
- lv_slider_set_value(obj, intval, LV_ANIM_ON);
- return;
+ return update ? lv_slider_set_value(obj, intval, LV_ANIM_ON)
+ : hasp_out_int(obj, attr, lv_slider_get_value(obj));
} else if(check_obj_type(objtype, LV_HASP_LED)) {
- lv_led_set_bright(obj, (uint8_t)val);
- return;
+ return update ? lv_led_set_bright(obj, (uint8_t)val) : hasp_out_int(obj, attr, lv_led_get_bright(obj));
} else if(check_obj_type(objtype, LV_HASP_GAUGE)) {
- lv_gauge_set_value(obj, 0, intval);
- return;
+ return update ? lv_gauge_set_value(obj, 0, intval) : hasp_out_int(obj, attr, lv_gauge_get_value(obj, 0));
} else if(check_obj_type(objtype, LV_HASP_ROLLER)) {
lv_roller_set_selected(obj, val, LV_ANIM_ON);
return;
} else if(check_obj_type(objtype, LV_HASP_BAR)) {
- lv_bar_set_value(obj, intval, LV_ANIM_OFF);
- return;
+ return update ? lv_bar_set_value(obj, intval, LV_ANIM_ON) : hasp_out_int(obj, attr, lv_bar_get_value(obj));
} else if(check_obj_type(objtype, LV_HASP_CPICKER)) {
return update ? (void)lv_cpicker_set_color(obj, haspPayloadToColor(payload))
: hasp_out_color(obj, attr, lv_cpicker_get_color(obj));
@@ -794,9 +791,10 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
* **************************/
static inline bool is_true(const char * s)
{
- return (!strcmp_P(s, PSTR("true")) || !strcmp_P(s, PSTR("TRUE")) || !strcmp_P(s, PSTR("1")) ||
+ return (!strcmp_P(s, PSTR("true")) || !strcmp_P(s, PSTR("TRUE")) || !strcmp_P(s, PSTR("True")) ||
!strcmp_P(s, PSTR("on")) || !strcmp_P(s, PSTR("ON")) || !strcmp_P(s, PSTR("On")) ||
- !strcmp_P(s, PSTR("yes")) || !strcmp_P(s, PSTR("YES")) || !strcmp_P(s, PSTR("Yes")));
+ !strcmp_P(s, PSTR("yes")) || !strcmp_P(s, PSTR("YES")) || !strcmp_P(s, PSTR("Yes")) ||
+ !strcmp_P(s, PSTR("1")));
}
static inline bool only_digits(const char * s)
@@ -808,17 +806,17 @@ static inline bool only_digits(const char * s)
return strlen(s) == digits;
}
-void hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val)
+void inline hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val)
{
hasp_send_obj_attribute_int(obj, attr, val);
}
-void hasp_out_str(lv_obj_t * obj, const char * attr, const char * data)
+void inline hasp_out_str(lv_obj_t * obj, const char * attr, const char * data)
{
hasp_send_obj_attribute_str(obj, attr, data);
}
-void hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color)
+void inline hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color)
{
hasp_send_obj_attribute_color(obj, attr, color);
}
diff --git a/src/hasp_button.cpp b/src/hasp_button.cpp
deleted file mode 100644
index 400a0b84..00000000
--- a/src/hasp_button.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "Arduino.h"
-#include "ArduinoLog.h"
-#include "AceButton.h"
-
-#include "hasp_conf.h"
-#include "lv_conf.h"
-
-#include "hasp_mqtt.h" // testing memory consumption
-#include "hasp_button.h"
-#include "hasp_dispatch.h"
-
-using namespace ace_button;
-static AceButton * button[HASP_NUM_INPUTS]; // Connect your button between pin 2 and GND
-
-static void button_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState)
-{
- char buffer[8];
- switch(eventType) {
- case 0: // AceButton::kEventPressed:
- memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
- break;
- case 2: // AceButton::kEventClicked:
- memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
- break;
- // case AceButton::kEventDoubleClicked:
- // memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer));
- // break;
- case 4: // AceButton::kEventLongPressed:
- memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
- break;
- case 5: // AceButton::kEventRepeatPressed:
- return; // Fix needed for switches
- memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
- break;
- case 1: // AceButton::kEventReleased:
- memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
- break;
- }
- dispatch_button(button->getId(), buffer);
-}
-
-void buttonSetup(void)
-{
- // button[0] = new Button(2);
- button[1] = new AceButton(3, HIGH, 1);
- button[2] = new AceButton(4, HIGH, 2);
-
- Log.verbose(F("BTNS: setup(): ready"));
-
- ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig();
- buttonConfig->setEventHandler(button_event_cb);
-
- // Features
- buttonConfig->setFeature(ButtonConfig::kFeatureClick);
- buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
- buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
- // buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
- // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
-
- // Delays
- buttonConfig->setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
- buttonConfig->setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
- buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
- buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
- buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME);
-}
-
-void IRAM_ATTR buttonLoop(void)
-{
- // Should be called every 4-5ms or faster, for the default debouncing time
- // of ~20ms.
- for(uint8_t i = 0; i < HASP_NUM_INPUTS; i++) {
- if(button[i]) button[i]->check();
- }
-}
diff --git a/src/hasp_button.h b/src/hasp_button.h
deleted file mode 100644
index e19bb556..00000000
--- a/src/hasp_button.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#if HASP_USE_BUTTON
-
-#ifndef HASP_BUTTON_H
-#define HASP_BUTTON_H
-
-void buttonSetup(void);
-void IRAM_ATTR buttonLoop(void);
-
-#endif
-#endif
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index 86fec041..c2da806a 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -1,6 +1,7 @@
#include "Arduino.h"
-#include "ArduinoJson.h"
#include "ArduinoLog.h"
+#include "ArduinoJson.h"
+#include "StreamUtils.h"
#include "hasp_config.h"
#include "hasp_debug.h"
@@ -13,21 +14,16 @@
#include "hasp_conf.h"
-#if HASP_USE_SPIFFS>0
+#if HASP_USE_SPIFFS > 0
#include // Include the SPIFFS library
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
#endif
-#if HASP_USE_EEPROM>0
+#if HASP_USE_EEPROM > 0
#include "EEPROM.h"
#endif
-#ifndef FPSTR
-#define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
-#endif
-
-
void confDebugSet(const char * name)
{
/*char buffer[128];
@@ -77,13 +73,17 @@ void configStartDebug(bool setupdebug, String & configFile)
{
if(setupdebug) {
debugStart(); // Debug started, now we can use it; HASP header sent
+#if HASP_USE_SPIFFS > 0
Log.notice(F("FILE: [SUCCESS] SPI flash FS mounted"));
-#if HASP_USE_SPIFFS>0
spiffsInfo();
spiffsList();
#endif
}
+#if HASP_USE_SPIFFS > 0
Log.notice(F("CONF: Loading %s"), configFile.c_str());
+#else
+ Log.notice(F("CONF: reading EEPROM"));
+#endif
}
void configGetConfig(JsonDocument & settings, bool setupdebug = false)
@@ -91,9 +91,10 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
String configFile((char *)0);
configFile.reserve(128);
configFile = String(FPSTR(HASP_CONFIG_FILE));
+ DeserializationError error;
-#if HASP_USE_SPIFFS>0
- File file = SPIFFS.open(configFile, "r");
+#if HASP_USE_SPIFFS > 0
+ File file = SPIFFS.open(configFile, "r");
if(file) {
size_t size = file.size();
@@ -102,7 +103,7 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
return;
}
- DeserializationError error = deserializeJson(settings, file);
+ error = deserializeJson(settings, file);
if(!error) {
file.close();
@@ -126,17 +127,26 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
return;
}
}
+#else
+
+#if HASP_USE_EEPROM > 0
+ EepromStream eepromStream(0, 1024);
+ error = deserializeJson(settings, eepromStream);
+#endif
+
#endif
// File does not exist or error reading file
if(setupdebug) {
debugPreSetup(settings[F("debug")]);
}
-
configStartDebug(setupdebug, configFile);
- Log.error(F("CONF: Failed to load %s"), configFile.c_str());
-}
+#if HASP_USE_SPIFFS > 0
+ Log.error(F("CONF: Failed to load %s"), configFile.c_str());
+#endif
+}
+/*
void configBackupToEeprom()
{
#if HASP_USE_SPIFFS>0
@@ -165,10 +175,9 @@ void configBackupToEeprom()
}
#endif
}
-
+*/
void configWriteConfig()
{
-#if HASP_USE_SPIFFS>0
String configFile((char *)0);
configFile.reserve(128);
configFile = String(FPSTR(HASP_CONFIG_FILE));
@@ -190,14 +199,15 @@ void configWriteConfig()
bool writefile = false;
bool changed = false;
-#if HASP_USE_WIFI
+#if HASP_USE_WIFI>0
if(settings[F("wifi")].as().isNull()) settings.createNestedObject(F("wifi"));
changed = wifiGetConfig(settings[F("wifi")]);
if(changed) {
Log.verbose(F("WIFI: Settings changed"));
writefile = true;
}
-#if HASP_USE_MQTT
+#endif
+#if HASP_USE_MQTT>0
if(settings[F("mqtt")].as().isNull()) settings.createNestedObject(F("mqtt"));
changed = mqttGetConfig(settings[F("mqtt")]);
if(changed) {
@@ -206,7 +216,7 @@ void configWriteConfig()
writefile = true;
}
#endif
-#if HASP_USE_TELNET
+#if HASP_USE_TELNET>0
if(settings[F("telnet")].as().isNull()) settings.createNestedObject(F("telnet"));
changed = telnetGetConfig(settings[F("telnet")]);
if(changed) {
@@ -215,7 +225,7 @@ void configWriteConfig()
writefile = true;
}
#endif
-#if HASP_USE_MDNS
+#if HASP_USE_MDNS>0
if(settings[F("mdns")].as().isNull()) settings.createNestedObject(F("mdns"));
changed = mdnsGetConfig(settings[F("mdns")]);
if(changed) {
@@ -223,7 +233,7 @@ void configWriteConfig()
writefile = true;
}
#endif
-#if HASP_USE_HTTP
+#if HASP_USE_HTTP>0
if(settings[F("http")].as().isNull()) settings.createNestedObject(F("http"));
changed = httpGetConfig(settings[F("http")]);
if(changed) {
@@ -231,7 +241,6 @@ void configWriteConfig()
configOutput(settings[F("http")]);
writefile = true;
}
-#endif
#endif
if(settings[F("debug")].as().isNull()) settings.createNestedObject(F("debug"));
@@ -258,6 +267,7 @@ void configWriteConfig()
// changed |= otaGetConfig(settings[F("ota")].as());
if(writefile) {
+#if HASP_USE_SPIFFS > 0
File file = SPIFFS.open(configFile, "w");
if(file) {
Log.notice(F("CONF: Writing %s"), configFile.c_str());
@@ -265,36 +275,71 @@ void configWriteConfig()
file.close();
if(size > 0) {
Log.verbose(F("CONF: [SUCCESS] Saved %s"), configFile.c_str());
- configBackupToEeprom();
- return;
+ // configBackupToEeprom();
+ } else {
+ Log.error(F("CONF: Failed to write %s"), configFile.c_str());
}
+ } else {
+ Log.error(F("CONF: Failed to write %s"), configFile.c_str());
}
+#endif
- Log.error(F("CONF: Failed to write %s"), configFile.c_str());
+ // Method 1
+ // Log.verbose(F("CONF: Writing to EEPROM"));
+ // EepromStream eepromStream(0, 1024);
+ // WriteBufferingStream bufferedWifiClient{eepromStream, 512};
+ // serializeJson(doc, bufferedWifiClient);
+ // bufferedWifiClient.flush(); // <- OPTIONAL
+ // eepromStream.flush(); // (for ESP)
+
+#if defined(STM32F4xx)
+ // Method 2
+ Log.verbose(F("CONF: Writing to EEPROM"));
+ char buffer[1024 + 128];
+ size_t size = serializeJson(doc, buffer, sizeof(buffer));
+ if(size > 0) {
+ uint16_t i;
+ for(i = 0; i < size; i++) eeprom_buffered_write_byte(i, buffer[i]);
+ eeprom_buffered_write_byte(i, 0);
+ eeprom_buffer_flush();
+ Log.verbose(F("CONF: [SUCCESS] Saved EEPROM"));
+ } else {
+ Log.error(F("CONF: Failed to save config to EEPROM"));
+ }
+#endif
} else {
- Log.notice(F("CONF: Configuration was not changed"));
+ Log.notice(F("CONF: Configuration did not change"));
}
-#endif
+ configOutput(settings);
}
void configSetup()
{
-#if HASP_USE_SPIFFS>0
- if(!SPIFFS.begin()) {
-#endif
-
-#if HASP_USE_SPIFFS>0
- } else {
-#endif
- DynamicJsonDocument settings(1024 + 128);
- Serial.print(__FILE__);
- Serial.println(__LINE__);
+ DynamicJsonDocument settings(1024 + 128);
- configGetConfig(settings, true);
+ for(uint8_t i = 0; i < 2; i++) {
+ Serial.print(__FILE__);
+ Serial.println(__LINE__);
- Log.error(F("FILE: SPI flash init failed. Unable to mount FS: Using default settings..."));
-#if HASP_USE_SPIFFS>0
+ if(i == 0) {
+#if HASP_USE_SPIFFS > 0
+ EepromStream eepromStream(0, 2048);
+ DeserializationError error = deserializeJson(settings, eepromStream);
+#else
+ continue;
+#endif
+ } else {
+#if HASP_USE_SPIFFS > 0
+ if(!SPIFFS.begin()) {
+ Log.error(F("FILE: SPI flash init failed. Unable to mount FS: Using default settings..."));
+ return;
+ }
+#endif
+ configGetConfig(settings, true);
+ }
+
+ //#if HASP_USE_SPIFFS > 0
Log.verbose(F("Loading debug settings"));
debugSetConfig(settings[F("debug")]);
Log.verbose(F("Loading GUI settings"));
@@ -303,29 +348,30 @@ void configSetup()
haspSetConfig(settings[F("hasp")]);
// otaGetConfig(settings[F("ota")]);
-#if HASP_USE_WIFI
+#if HASP_USE_WIFI>0
Log.verbose(F("Loading WiFi settings"));
wifiSetConfig(settings[F("wifi")]);
-#if HASP_USE_MQTT
+#endif
+#if HASP_USE_MQTT>0
Log.verbose(F("Loading MQTT settings"));
mqttSetConfig(settings[F("mqtt")]);
#endif
-#if HASP_USE_TELNET
+#if HASP_USE_TELNET>0
Log.verbose(F("Loading Telnet settings"));
telnetSetConfig(settings[F("telnet")]);
#endif
-#if HASP_USE_MDNS
+#if HASP_USE_MDNS>0
Log.verbose(F("Loading MDNS settings"));
mdnsSetConfig(settings[F("mdns")]);
#endif
-#if HASP_USE_HTTP
+#if HASP_USE_HTTP>0
Log.verbose(F("Loading HTTP settings"));
httpSetConfig(settings[F("http")]);
#endif
-#endif
+ // }
+ Log.notice(F("User configuration loaded"));
}
- Log.notice(F("User configuration loaded"));
-#endif
+ //#endif
}
void configOutput(const JsonObject & settings)
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index 854b9db4..38033453 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -15,7 +15,7 @@
#endif
#include "hasp_hal.h"
-#if HASP_USE_MQTT>0
+#if HASP_USE_MQTT > 0
#include "hasp_mqtt.h"
#endif
@@ -31,11 +31,11 @@
#define SERIAL_SPEED 115200
#endif
-#if HASP_USE_TELNET != 0
+#if HASP_USE_TELNET > 0
#include "hasp_telnet.h"
#endif
-#if HASP_USE_SYSLOG != 0
+#if HASP_USE_SYSLOG > 0
#include "Syslog.h"
#ifndef SYSLOG_SERVER
@@ -71,9 +71,11 @@ Syslog * syslog;
#endif // USE_SYSLOG
// Serial Settings
+uint8_t serialInputIndex = 0; // Empty buffer
+char serialInputBuffer[1024];
uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10
bool debugSerialStarted = false;
-bool debugAnsiCodes = true;
+bool debugAnsiCodes = true;
//#define TERM_COLOR_Black "\u001b[30m"
#define TERM_COLOR_GRAY "\e[37m"
@@ -94,11 +96,12 @@ String debugHaspHeader()
{
String header((char *)0);
header.reserve(256);
- header = F(" _____ _____ _____ _____\r\n"
- " | | | _ | __| _ |\r\n"
- " | | |__ | __|\r\n"
- " |__|__|__|__|_____|__|\r\n"
- " Home Automation Switch Plate\r\n");
+ if(debugAnsiCodes) header += TERM_COLOR_YELLOW;
+ header += F(" _____ _____ _____ _____\r\n"
+ " | | | _ | __| _ |\r\n"
+ " | | |__ | __|\r\n"
+ " |__|__|__|__|_____|__|\r\n"
+ " Home Automation Switch Plate\r\n");
char buffer[128];
snprintf(buffer, sizeof(buffer), PSTR(" Open Hardware edition v%u.%u.%u\r\n"), HASP_VERSION_MAJOR,
HASP_VERSION_MINOR, HASP_VERSION_REVISION);
@@ -119,7 +122,7 @@ void debugStart()
// log/logf method)
}
-#if HASP_USE_SYSLOG != 0
+#if HASP_USE_SYSLOG > 0
void syslogSend(uint8_t priority, const char * debugText)
{
if(strlen(debugSyslogHost) != 0 && WiFi.isConnected()) {
@@ -130,7 +133,7 @@ void syslogSend(uint8_t priority, const char * debugText)
void debugSetup()
{
-#if HASP_USE_SYSLOG != 0
+#if HASP_USE_SYSLOG > 0
syslog = new Syslog(syslogClient, debugSyslogProtocol == 0 ? SYSLOG_PROTO_IETF : SYSLOG_PROTO_BSD);
syslog->server(debugSyslogHost, debugSyslogPort);
syslog->deviceHostname(mqttNodeName);
@@ -155,7 +158,7 @@ bool debugGetConfig(const JsonObject & settings)
if(debugTelePeriod != settings[FPSTR(F_DEBUG_TELEPERIOD)].as()) changed = true;
settings[FPSTR(F_DEBUG_TELEPERIOD)] = debugTelePeriod;
-#if HASP_USE_SYSLOG != 0
+#if HASP_USE_SYSLOG > 0
if(strcmp(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)].as().c_str()) != 0) changed = true;
settings[FPSTR(F_CONFIG_HOST)] = debugSyslogHost;
@@ -193,7 +196,7 @@ bool debugSetConfig(const JsonObject & settings)
changed |= configSet(debugTelePeriod, settings[FPSTR(F_DEBUG_TELEPERIOD)], PSTR("debugTelePeriod"));
/* Syslog Settings*/
-#if HASP_USE_SYSLOG != 0
+#if HASP_USE_SYSLOG > 0
if(!settings[FPSTR(F_CONFIG_HOST)].isNull()) {
changed |= strcmp(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)]) != 0;
strncpy(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)], sizeof(debugSyslogHost));
@@ -216,21 +219,23 @@ static void debugPrintTimestamp(int level, Print * _logOutput)
time_t rawtime;
struct tm * timeinfo;
- //time(&rawtime);
- //timeinfo = localtime(&rawtime);
+ // time(&rawtime);
+ // timeinfo = localtime(&rawtime);
// strftime(buffer, sizeof(buffer), "%b %d %H:%M:%S.", timeinfo);
// Serial.println(buffer);
debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput);
- /* if(timeinfo->tm_year >= 120) {
- char buffer[64];
- strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S.", timeinfo); // Literal String
- _logOutput->print(buffer);
- _logOutput->printf(PSTR("%03lu]"), millis() % 1000);
- } else */ {
- _logOutput->printf(PSTR("[%20.3f]"), (float)millis() / 1000);
+ /* if(timeinfo->tm_year >= 120) {
+ char buffer[64];
+ strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S.", timeinfo); // Literal String
+ _logOutput->print(buffer);
+ _logOutput->printf(PSTR("%03lu]"), millis() % 1000);
+ } else */
+ {
+ uint32_t msecs = millis();
+ _logOutput->printf(PSTR("[%16d.%03d]"), msecs / 1000, msecs % 1000);
}
}
@@ -328,15 +333,17 @@ void debugPreSetup(JsonObject settings)
uint32_t baudrate = settings[FPSTR(F_CONFIG_BAUD)].as() * 10;
if(baudrate == 0) baudrate = SERIAL_SPEED;
- if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */
+ if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */
-#ifdef STM32_CORE_VERSION_MAJOR
- Serial.setRx(PA3); // User Serial2
- Serial.setTx(PA2);
+#if defined(STM32F4xx)
+#ifndef STM32_SERIAL1 // Define what Serial port to use for log output
+ Serial.setRx(PA3); // User Serial2
+ Serial.setTx(PA2);
+#endif
#endif
Serial.begin(baudrate); /* prepare for possible serial debug */
delay(10);
- Log.registerOutput(0, &Serial, LOG_LEVEL_VERBOSE, true);
+ Log.registerOutput(0, &Serial, LOG_LEVEL_VERBOSE, true);
debugSerialStarted = true;
Serial.println();
Log.trace(("Serial started at %u baud"), baudrate);
@@ -373,7 +380,26 @@ void debugLvgl(lv_log_level_t level, const char * file, uint32_t line, const cha
#endif
void debugLoop()
-{}
+{
+ while(Serial.available()) {
+ char ch = Serial.read();
+ Serial.print(ch);
+ if(ch == 13 || ch == 10) {
+ serialInputBuffer[serialInputIndex] = 0;
+ if(serialInputIndex > 0) dispatchCommand(serialInputBuffer);
+ serialInputIndex = 0;
+ } else {
+ if(serialInputIndex < sizeof(serialInputBuffer) - 1) {
+ serialInputBuffer[serialInputIndex++] = ch;
+ }
+ serialInputBuffer[serialInputIndex] = 0;
+ if(strcmp(serialInputBuffer, "jsonl=") == 0) {
+ dispatchJsonl(Serial);
+ serialInputIndex = 0;
+ }
+ }
+ }
+}
/*void printLocalTime()
{
diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp
index bed14991..ab227e64 100644
--- a/src/hasp_dispatch.cpp
+++ b/src/hasp_dispatch.cpp
@@ -38,7 +38,7 @@ void dispatchLoop()
void dispatchStatusUpdate()
{
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT>0
mqtt_send_statusupdate();
#endif
}
@@ -48,11 +48,15 @@ void dispatchOutput(int output, bool state)
int pin = 0;
if(pin >= 0) {
+ Log.notice(F("PIN OUTPUT STATE %d"),state);
#if defined(ARDUINO_ARCH_ESP32)
ledcWrite(99, state ? 1023 : 0); // ledChannel and value
+#elif defined(STM32F4xx)
+ digitalWrite(HASP_OUTPUT_PIN, state);
#else
- analogWrite(pin, state ? 1023 : 0);
+ digitalWrite(D1, state);
+ // analogWrite(pin, state ? 1023 : 0);
#endif
}
}
@@ -95,11 +99,6 @@ void dispatchAttribute(String strTopic, const char * payload)
{
if(strTopic.startsWith("p[")) {
dispatchButtonAttribute(strTopic, payload);
- } else if(strTopic.startsWith(F("output"))) {
-#if defined(ARDUINO_ARCH_ESP8266)
- uint8_t state = isON(payload) ? HIGH : LOW;
- digitalWrite(D1, state);
-#endif
} else if(strTopic == F("page")) {
dispatchPage(payload);
@@ -138,9 +137,12 @@ void dispatchPage(String strPageid)
String strPage((char *)0);
strPage.reserve(128);
strPage = haspGetPage();
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT > 0
mqtt_send_state(F("page"), strPage.c_str());
#endif
+#if HASP_USE_TASMOTA_SLAVE > 0
+ slave_send_state(F("page"), strPage.c_str());
+#endif
}
void dispatchClearPage(String strPageid)
@@ -159,12 +161,16 @@ void dispatchDim(String strDimLevel)
// Set the current state
if(strDimLevel.length() != 0) guiSetDim(strDimLevel.toInt());
dispatchPrintln(F("DIM"), strDimLevel);
-
-#if HASP_USE_MQTT
char buffer[8];
+#if defined(HASP_USE_MQTT) || defined(HASP_USE_TASMOTA_SLAVE)
itoa(guiGetDim(), buffer, DEC);
+#if HASP_USE_MQTT > 0
mqtt_send_state(F("dim"), buffer);
#endif
+#if HASP_USE_TASMOTA_SLAVE > 0
+ slave_send_state(F("dim"), buffer);
+#endif
+#endif
}
void dispatchBacklight(String strPayload)
@@ -177,14 +183,18 @@ void dispatchBacklight(String strPayload)
// Return the current state
strPayload = getOnOff(guiGetBacklight());
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT > 0
mqtt_send_state(F("light"), strPayload.c_str());
#endif
+#if HASP_USE_TASMOTA_SLAVE > 0
+ slave_send_state(F("light"), strPayload.c_str());
+#endif
+
}
void dispatchCommand(String cmnd)
{
- // dispatchPrintln(F("CMND"), cmnd);
+ dispatchPrintln(F("CMND"), cmnd);
if(cmnd.startsWith(F("page "))) {
cmnd = cmnd.substring(5, cmnd.length());
@@ -266,34 +276,46 @@ void dispatchJsonl(char * payload)
void dispatchIdle(const char * state)
{
-#if HASP_USE_MQTT>0
- mqtt_send_state(F("idle"), state);
-#else
+#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
Log.notice(F("OUT: idle = %s"), state);
+#else
+#if HASP_USE_MQTT > 0
+ mqtt_send_state(F("idle"), state);
+#endif
+#if HASP_USE_TASMOTA_SLAVE > 0
+ slave_send_state(F("idle"), state);
+#endif
#endif
}
void dispatchReboot(bool saveConfig)
{
if(saveConfig) configWriteConfig();
-#if HASP_USE_MQTT>0
+#if HASP_USE_MQTT > 0
mqttStop(); // Stop the MQTT Client first
#endif
debugStop();
-#if HASP_USE_WIFI>0
+#if HASP_USE_WIFI > 0
wifiStop();
#endif
Log.verbose(F("-------------------------------------"));
Log.notice(F("STOP: Properly Rebooting the MCU now!"));
Serial.flush();
- //halRestart();
+ halRestart();
}
void dispatch_button(uint8_t id, const char * event)
{
+#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
+ Log.notice(F("OUT: input%d = %s"), id, event);
+#else
#if HASP_USE_MQTT > 0
mqtt_send_input(id, event);
#endif
+#if HASP_USE_TASMOTA_SLAVE>0
+ slave_send_input(id, event);
+#endif
+#endif
}
void dispatchWebUpdate(const char * espOtaUrl)
@@ -306,10 +328,15 @@ void dispatchWebUpdate(const char * espOtaUrl)
void IRAM_ATTR dispatch_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
{
+#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
+ Log.notice(F("OUT: json = {\"p[%u].b[%u].%s\":\"%s\"}"), pageid, btnid, attribute, data);
+#else
#if HASP_USE_MQTT > 0
mqtt_send_obj_attribute_str(pageid, btnid, attribute, data);
-#else
- Log.notice(F("OUT: json = {\"p[%u].b[%u].%s\":\"%s\"}"), pageid, btnid, attribute, data);
+#endif
+#if HASP_USE_TASMOTA_SLAVE > 0
+ slave_send_obj_attribute_str(pageid, btnid, attribute, data);
+#endif
#endif
}
@@ -356,14 +383,14 @@ void dispatchConfig(const char * topic, const char * payload)
haspGetConfig(settings);
}
-#if HASP_USE_WIFI
+#if HASP_USE_WIFI > 0
else if(strcmp_P(topic, PSTR("wifi")) == 0) {
if(update)
wifiSetConfig(settings);
else
wifiGetConfig(settings);
}
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT > 0
else if(strcmp_P(topic, PSTR("mqtt")) == 0) {
if(update)
mqttSetConfig(settings);
@@ -371,11 +398,11 @@ void dispatchConfig(const char * topic, const char * payload)
mqttGetConfig(settings);
}
#endif
-#if HASP_USE_TELNET
+#if HASP_USE_TELNET > 0
// else if(strcmp_P(topic, PSTR("telnet")) == 0)
// telnetGetConfig(settings[F("telnet")]);
#endif
-#if HASP_USE_MDNS
+#if HASP_USE_MDNS > 0
else if(strcmp_P(topic, PSTR("mdns")) == 0) {
if(update)
mdnsSetConfig(settings);
@@ -383,7 +410,7 @@ void dispatchConfig(const char * topic, const char * payload)
mdnsGetConfig(settings);
}
#endif
-#if HASP_USE_HTTP
+#if HASP_USE_HTTP > 0
else if(strcmp_P(topic, PSTR("http")) == 0) {
if(update)
httpSetConfig(settings);
@@ -397,10 +424,15 @@ void dispatchConfig(const char * topic, const char * payload)
if(!update) {
settings.remove(F("pass")); // hide password in output
size_t size = serializeJson(doc, buffer, sizeof(buffer));
-#if HASP_USE_MQTT
- mqtt_send_state(F("config"), buffer);
-#else
+#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
Log.notice(F("OUT: config %s = %s"),topic,buffer);
+#else
+#if HASP_USE_MQTT > 0
+ mqtt_send_state(F("config"), buffer);
+#endif
+#if HASP_USE_TASMOTA > 0
+ slave_send_state(F("config"), buffer);
+#endif
#endif
}
}
diff --git a/src/hasp_eeprom.cpp b/src/hasp_eeprom.cpp
index 1aed0979..d53963fe 100644
--- a/src/hasp_eeprom.cpp
+++ b/src/hasp_eeprom.cpp
@@ -1,49 +1,23 @@
#include
#include "EEPROM.h"
-#include "hasp_debug.h"
-
-void eepromWrite(char addr, std::string & data);
-std::string eepromRead(char addr);
-
void eepromSetup()
{
+
+#if defined(STM32Fxx)
+ eeprom_buffer_fill();
+ char buffer[] = "{\"objid\":10,\"id\":1,\"page\":0,\"x\":10,\"y\":45,\"w\":220,\"h\":55,\"toggle\":\"TRUE\",\"txt\":\"Toggle Me\"}";
+ uint size = strlen(buffer);
+ uint16_t i;
+ for(i = 0; i < size; i++) eeprom_buffered_write_byte(i+4096, buffer[i]);
+ eeprom_buffered_write_byte(i+4096, 0);
+ // eeprom_buffer_flush();
+#endif
+
+ // ESP8266 // Don't start at boot, only at write
// EEPROM.begin(1024);
// debugPrintln("EEPROM: Started Eeprom");
}
void eepromLoop()
-{}
-
-void eepromUpdate(uint16_t addr, char ch)
-{
- if(EEPROM.read(addr) != ch) {
- EEPROM.write(addr, ch);
- }
-}
-
-void eepromWrite(uint16_t addr, std::string & data)
-{
- int count = data.length();
- for(int i = 0; i < count; i++) {
- eepromUpdate(addr + i, data[i]);
- }
- eepromUpdate(addr + count, '\0');
- // EEPROM.commit();
-}
-
-std::string eepromRead(uint16_t addr)
-{
- char data[1024]; // Max 1024 Bytes
- int len = 0;
- unsigned char k;
- k = EEPROM.read(addr);
- while(k != '\0' && len < 1023) // Read until null character
- {
- k = EEPROM.read(addr + len);
- if((uint8_t(k) < 32) || (uint8_t(k) > 127)) break; // check for printable ascii, includes '\0'
- data[len] = k;
- len++;
- }
- return std::string(data);
-}
\ No newline at end of file
+{}
\ No newline at end of file
diff --git a/src/hasp_ethernet.cpp b/src/hasp_ethernet.cpp
new file mode 100644
index 00000000..d6f82bff
--- /dev/null
+++ b/src/hasp_ethernet.cpp
@@ -0,0 +1,96 @@
+#include
+#include "ArduinoJson.h"
+#include "ArduinoLog.h"
+#include "hasp_conf.h"
+#include "hasp_hal.h"
+
+#if HASP_USE_ETHERNET > 0
+
+EthernetClient EthClient;
+IPAddress ip;
+
+void ethernetSetup()
+{
+#if USE_BUILTIN_ETHERNET > 0
+ // start Ethernet and UDP
+ Log.notice(F("ETH: Begin Ethernet LAN8720"));
+ if(Ethernet.begin() == 0) {
+ Log.notice(F("ETH: Failed to configure Ethernet using DHCP"));
+ } else {
+ ip = Ethernet.localIP();
+ Log.notice(F("ETH: DHCP Success got IP %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
+ }
+
+ Log.notice(F("ETH: MAC Address %s"), halGetMacAddress(0, ":"));
+
+#else
+ byte mac[6];
+ uint32_t baseUID = (uint32_t)UID_BASE;
+ mac[0] = 0x00;
+ mac[1] = 0x80;
+ mac[2] = 0xE1;
+ mac[3] = (baseUID & 0x00FF0000) >> 16;
+ mac[4] = (baseUID & 0x0000FF00) >> 8;
+ mac[5] = (baseUID & 0x000000FF);
+
+ char ethHostname[12];
+ memset(ethHostname, 0 ,sizeof(ethHostname));
+ snprintf(ethHostname, sizeof(ethHostname), PSTR("HASP-%02x%02x%02x"), mac[3], mac[4], mac[5]);
+
+ Ethernet.setCsPin(W5500_CS);
+ Ethernet.setRstPin(W5500_RST);
+ Ethernet.setHostname(ethHostname);
+ Log.notice(F("ETH: Begin Ethernet W5500"));
+ if(Ethernet.begin(mac) == 0) {
+ Log.notice(F("ETH: Failed to configure Ethernet using DHCP"));
+ } else {
+ ip = Ethernet.localIP();
+ Log.notice(F("ETH: DHCP Success got IP %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
+ }
+#endif
+}
+
+void ethernetLoop(void)
+{
+ switch(Ethernet.maintain()) {
+ case 1:
+ // renewed fail
+ Log.notice(F("ETH: Error: renewed fail"));
+ break;
+
+ case 2:
+ // renewed success
+ ip = Ethernet.localIP();
+ Log.notice(F("ETH: DHCP Renew Success got IP=%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
+ break;
+
+ case 3:
+ // rebind fail
+ Log.notice(F("Error: rebind fail"));
+ break;
+
+ case 4:
+ // rebind success
+ ip = Ethernet.localIP();
+ Log.notice(F("ETH: DHCP Rebind Success got IP=%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
+ break;
+
+ default:
+ // nothing happened
+ break;
+ }
+}
+
+bool ethernetEvery5Seconds()
+{
+ bool state;
+#if USE_BUILTIN_ETHERNET > 0
+ state = Ethernet.linkStatus() == LinkON;
+#else
+ state = Ethernet.link() == 1;
+#endif
+ Log.warning(F("ETH: %s"), state ? F("ONLINE") : F("OFFLINE"));
+ return state;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/hasp_ethernet.h b/src/hasp_ethernet.h
new file mode 100644
index 00000000..177f0908
--- /dev/null
+++ b/src/hasp_ethernet.h
@@ -0,0 +1,8 @@
+#ifndef HASP_ETHERNET_H
+#define HASP_ETHERNET_H
+
+void ethernetSetup();
+void ethernetLoop(void);
+
+bool ethernetEvery5Seconds();
+#endif
\ No newline at end of file
diff --git a/src/hasp_gpio.cpp b/src/hasp_gpio.cpp
index 1ab5cefb..885278db 100644
--- a/src/hasp_gpio.cpp
+++ b/src/hasp_gpio.cpp
@@ -1,10 +1,254 @@
-#include
-#include "ArduinoJson.h"
+#include "Arduino.h"
+#include "ArduinoLog.h"
+
+#include "AceButton.h"
+#include "lv_conf.h" // For timing defines
+
+#include "hasp_conf.h"
+#include "hasp_gpio.h"
+#include "hasp_dispatch.h"
+
+#define HASP_NUM_GPIO_CONFIG 5
+
+uint8_t gpioUsedInputCount = 0;
+uint16_t gpioConfig[HASP_NUM_GPIO_CONFIG];
+
+using namespace ace_button;
+static AceButton * button[HASP_NUM_INPUTS];
+
+struct hasp_gpio_config_t {
+ const uint8_t pin;
+ const uint8_t group;
+ const uint8_t io_mode;
+ bool default_state;
+};
+
+// An array of button pins, led pins, and the led states. Cannot be const
+// because ledState is mutable.
+ hasp_gpio_config_t gpioConfig2[HASP_NUM_GPIO_CONFIG] = {
+ {2, 8, INPUT, LOW},
+ {3, 9, OUTPUT, LOW},
+ {4, 10, INPUT, HIGH},
+ {5, 11, OUTPUT, LOW},
+ {6, 12, INPUT, LOW},
+};
+
+#if defined(ARDUINO_ARCH_ESP32)
+class TouchConfig : public ButtonConfig {
+ public:
+ TouchConfig();
+
+ protected:
+ // Number of iterations to sample the capacitive switch. Higher number
+ // provides better smoothing but increases the time taken for a single read.
+ static const uint8_t kSamples = 10;
+
+ // The threshold value which is considered to be a "touch" on the switch.
+ static const long kTouchThreshold = 70;
+
+ int readButton(uint8_t pin) override
+ {
+ // long total = mSensor.capacitiveSensor(kSamples);
+ return (touchRead(pin) > kTouchThreshold) ? LOW : HIGH;
+ }
+};
+
+TouchConfig touchConfig();
+#endif
+
+static void gpio_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState)
+{
+ char buffer[16];
+ switch(eventType) {
+ case 0: // AceButton::kEventPressed:
+ memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
+ break;
+ case 2: // AceButton::kEventClicked:
+ memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
+ break;
+ case AceButton::kEventDoubleClicked:
+ memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer));
+ break;
+ case 4: // AceButton::kEventLongPressed:
+ memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
+ break;
+ case 5: // AceButton::kEventRepeatPressed:
+ // return; // Fix needed for switches
+ memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
+ break;
+ case 1: // AceButton::kEventReleased:
+ memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
+ break;
+ default:
+ memcpy_P(buffer, PSTR("UNKNOWN"), sizeof(buffer));
+ }
+ dispatch_button(button->getId(), buffer);
+}
+
+void aceButtonSetup(void)
+{
+ ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig();
+ buttonConfig->setEventHandler(gpio_event_cb);
+
+ // Features
+ buttonConfig->setFeature(ButtonConfig::kFeatureClick);
+ buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
+ buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
+ // buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
+ // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
+
+ // Delays
+ buttonConfig->setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
+ buttonConfig->setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
+ buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
+ buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
+ buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME);
+}
+
+void IRAM_ATTR gpioLoop(void)
+{
+ // Should be called every 4-5ms or faster, for the default debouncing time of ~20ms.
+ for(uint8_t i = 0; i < gpioUsedInputCount; i++) {
+ if(button[i]) button[i]->check();
+ }
+}
+
+void gpioAddButton( uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
+{
+
+
+ uint8_t i;
+ for(i = 0; i < HASP_NUM_INPUTS; i++) {
+
+ if(!button[i]) {
+ button[i] = new AceButton(pin, default_state, channel);
+ // button[i]->init(pin, default_state, channel);
+
+ if(button[i]) {
+ pinMode(pin, input_mode);
+
+ ButtonConfig * buttonConfig = button[i]->getButtonConfig();
+ buttonConfig->setEventHandler(gpio_event_cb);
+ buttonConfig->setFeature(ButtonConfig::kFeatureClick);
+ buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
+ buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
+ buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
+ buttonConfig->clearFeature(
+ ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
+
+ Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel,
+ input_mode, default_state);
+ gpioUsedInputCount = i + 1;
+ return;
+ }
+ }
+ }
+ Log.error(F("GPIO: Failed to create Button%d pin %d (channel %d). All %d slots available are in use!"), i, pin,
+ channel, HASP_NUM_INPUTS);
+}
+
+void gpioAddTouchButton( uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
+{
+ uint8_t i;
+ for(i = 0; i < HASP_NUM_INPUTS; i++) {
+
+ if(!button[i]) {
+ button[i] = new AceButton();
+
+ if(button[i]) {
+ pinMode(pin, input_mode);
+
+ ButtonConfig * buttonConfig = button[i]->getButtonConfig();
+ buttonConfig->setEventHandler(gpio_event_cb);
+ buttonConfig->setFeature(ButtonConfig::kFeatureClick);
+ buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
+ buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
+ buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
+ buttonConfig->clearFeature(
+ ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
+
+ Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel,
+ input_mode, default_state);
+ gpioUsedInputCount = i + 1;
+ return;
+ }
+ }
+ }
+ Log.error(F("GPIO: Failed to create Button%d pin %d (channel %d). All %d slots available are in use!"), i, pin,
+ channel, HASP_NUM_INPUTS);
+}
void gpioSetup()
{
+ aceButtonSetup();
+
+ // gpioConfig[0] = PD15 * 256 + 5 + (INPUT << 3);
#if defined(ARDUINO_ARCH_ESP8266)
+ gpioAddButton( D2, INPUT_PULLUP, HIGH, 1);
pinMode(D1, OUTPUT);
- pinMode(D2, INPUT_PULLUP);
#endif
+
+#if defined(ARDUINO_ARCH_ESP32)
+ gpioAddButton( D2, INPUT, HIGH, 1);
+ pinMode(D1, OUTPUT);
+#endif
+
+ for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
+ uint8_t pin = (gpioConfig[i] >> 8) & 0xFF;
+ uint8_t channel = gpioConfig[i] & 0b111; // 3bit
+ uint8_t input_mode = (gpioConfig[i] >> 3) & 0b11; // 2bit gpio mode
+ //uint8_t input_mode = gpioConfig[i].io_mode
+ uint8_t gpiotype = (gpioConfig[i] >> 5) & 0b111; // 3bit
+ uint8_t default_state = gpioConfig[i] & 0b1; // 1bit: 0=LOW, 1=HIGH
+
+ switch(input_mode) {
+ case 1:
+ input_mode = OUTPUT;
+ break;
+ case 2:
+ input_mode = INPUT_PULLUP;
+ break;
+#ifndef ARDUINO_ARCH_ESP8266
+ case 3:
+ input_mode = INPUT_PULLDOWN;
+ break;
+#endif
+ default:
+ input_mode = INPUT;
+ }
+
+ switch(gpiotype) {
+ case HASP_GPIO_SWITCH:
+ case HASP_GPIO_BUTTON:
+ // gpioAddButton(gpioConfig[i].io_mode.pin, input_mode, gpioConfig[i].default_state, gpioConfig[i].group);
+ break;
+
+ case HASP_GPIO_RELAY:
+ pinMode(pin, OUTPUT);
+ break;
+
+ // case HASP_GPIO_LED:
+ case HASP_GPIO_PWM:
+ case HASP_GPIO_BACKLIGHT:
+ pinMode(pin, OUTPUT);
+#if defined(ARDUINO_ARCH_ESP32)
+ // configure LED PWM functionalitites
+ ledcSetup(channel, 20000, 10);
+ // attach the channel to the GPIO to be controlled
+ ledcAttachPin(pin, channel);
+#endif
+ break;
+ }
+ }
+
+ /*
+ #if defined(ARDUINO_ARCH_ESP8266)
+ pinMode(D1, OUTPUT);
+ pinMode(D2, INPUT_PULLUP);
+ #endif
+ #if defined(STM32F4xx)
+ pinMode(HASP_OUTPUT_PIN, OUTPUT);
+ pinMode(HASP_INPUT_PIN, INPUT);
+ #endif
+ */
}
\ No newline at end of file
diff --git a/src/hasp_gpio.h b/src/hasp_gpio.h
index 075f3a12..9a5c3b91 100644
--- a/src/hasp_gpio.h
+++ b/src/hasp_gpio.h
@@ -1,3 +1,25 @@
+#ifndef HASP_GPIO_H
+#define HASP_GPIO_H
+
#include "ArduinoJson.h"
-void gpioSetup();
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gpioSetup(void);
+void IRAM_ATTR gpioLoop(void);
+
+enum lv_hasp_gpio_type_t {
+ HASP_GPIO_SWITCH = 0,
+ HASP_GPIO_BUTTON = 1,
+ HASP_GPIO_RELAY = 2,
+ HASP_GPIO_PWM = 3,
+ HASP_GPIO_BACKLIGHT = 4,
+};
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 021b890a..7c33af36 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -18,7 +18,7 @@
//#include "lv_ex_conf.h"
//#include "tpcal.h"
-#if HASP_USE_PNGDECODE
+#if HASP_USE_PNGDECODE > 0
#include "png_decoder.h"
#endif
@@ -26,7 +26,7 @@
#define TOUCH_DRIVER 0
#endif
-#if HASP_USE_SPIFFS
+#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
@@ -41,6 +41,11 @@ File pFileOut;
#endif
uint8_t guiSnapshot = 0;
+#if defined(STM32F4xx)
+//#include
+// EthernetWebServer * webClient(0);
+#endif
+
#if defined(ARDUINO_ARCH_ESP8266)
#include
ESP8266WebServer * webClient; // for snatshot
@@ -75,10 +80,7 @@ static uint8_t guiRotation = TFT_ROTATION;
#if ESP32 > 0 || ESP8266 > 0
static Ticker tick; /* timer for interrupt handler */
#else
-static Ticker tick(lv_tick_handler,guiTickPeriod);
-uint8_t serialInputIndex = 0; // Empty buffer
-char serialInputBuffer[1024];
-
+static Ticker tick(lv_tick_handler, guiTickPeriod);
#endif
static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */
static uint16_t calData[5] = {0, 65535, 0, 65535, 0};
@@ -174,14 +176,15 @@ static bool guiCheckSleep()
/* Flush VDB bytes to a stream */
static void gui_take_screenshot(uint8_t * data_p, size_t len)
{
-#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
size_t res = 0;
switch(guiSnapshot) {
+#if HASP_USE_SPIFFS > 0
case 1:
res = pFileOut.write(data_p, len);
break;
+#endif
case 2:
- res = webClient->client().write(data_p, len);
+ res = httpClientWrite(data_p, len);
break;
default:
res = 0; // nothing to do
@@ -189,7 +192,6 @@ static void gui_take_screenshot(uint8_t * data_p, size_t len)
if(res != len) {
Log.warning(F("GUI: Pixelbuffer not completely sent"));
}
-#endif
}
/* Experimetnal Display flushing */
@@ -200,7 +202,6 @@ static void IRAM_ATTR tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * are
/* Update TFT */
tft.startWrite(); /* Start new TFT transaction */
tft.setWindow(area->x1, area->y1, area->x2, area->y2); /* set the working window */
- tft.setSwapBytes(true); /* set endianess */
tft.pushPixels((uint16_t *)color_p, len); /* Write words at once */
tft.endWrite(); /* terminate TFT transaction */
@@ -306,14 +307,6 @@ static void IRAM_ATTR lv_tick_handler(void)
lv_tick_inc(guiTickPeriod);
}
-#ifdef STM32_CORE_VERSION
-void Update_IT_callback(void)
-{
- Serial.print("?");
- lv_tick_inc(guiTickPeriod);
-}
-#endif
-
/* Reading input device (simulated encoder here) */
/*bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data)
{
@@ -628,6 +621,14 @@ void guiSetup()
{
/* TFT init */
tft.begin();
+ tft.setSwapBytes(true); /* set endianess */
+
+#ifdef USE_DMA_TO_TFT
+ // DMA - should work with STM32F2xx/F4xx/F7xx processors
+ // NOTE: >>>>>> DMA IS FOR SPI DISPLAYS ONLY <<<<<<
+ tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767)
+#endif
+
tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */
#if TOUCH_DRIVER == 0
tft.setTouch(calData);
@@ -656,14 +657,14 @@ void guiSetup()
#else
static lv_disp_buf_t disp_buf;
static lv_color_t guiVdbBuffer1[16 * 512u]; // 16 KBytes
- static lv_color_t guiVdbBuffer2[16 * 512u]; // 16 KBytes
+ // static lv_color_t guiVdbBuffer2[16 * 512u]; // 16 KBytes
guiVDBsize = sizeof(guiVdbBuffer1) / sizeof(guiVdbBuffer1[0]);
- lv_disp_buf_init(&disp_buf, guiVdbBuffer1, guiVdbBuffer2, guiVDBsize);
- //lv_disp_buf_init(&disp_buf, guiVdbBuffer1, NULL, guiVDBsize);
+ // lv_disp_buf_init(&disp_buf, guiVdbBuffer1, guiVdbBuffer2, guiVDBsize);
+ lv_disp_buf_init(&disp_buf, guiVdbBuffer1, NULL, guiVDBsize);
#endif
/* Initialize PNG decoder */
-#if HASP_USE_PNGDECODE != 0
+#if HASP_USE_PNGDECODE > 0
png_decoder_init();
#endif
@@ -673,8 +674,13 @@ void guiSetup()
lv_fs_if_init(); // auxilary file system drivers
#endif
- /* Dump TFT Cofiguration */
+ /* Dump TFT Configuration */
tftSetup(tft);
+#ifdef USE_DMA_TO_TFT
+ Log.verbose(F("TFT: DMA : ENABELD"));
+#else
+ Log.verbose(F("TFT: DMA : DISABELD"));
+#endif
/* Load User Settings */
// guiSetConfig(settings);
@@ -780,27 +786,27 @@ void guiSetup()
tick.attach_ms(guiTickPeriod, lv_tick_handler);
#else
-/*
-#if defined(TIM1)
- TIM_TypeDef * Instance = TIM1;
-#else
- TIM_TypeDef * Instance = TIM2;
-#endif
-*/
+ /*
+ #if defined(TIM1)
+ TIM_TypeDef * Instance = TIM1;
+ #else
+ TIM_TypeDef * Instance = TIM2;
+ #endif
+ */
// Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup()
// function is finished.
- /* static HardwareTimer * MyTim = new HardwareTimer(Instance);
- MyTim->pause();
- MyTim->setPrescaleFactor(1);
- MyTim->setMode(0, TIMER_OUTPUT_COMPARE, NC);
- MyTim->setOverflow(1000 * guiTickPeriod, MICROSEC_FORMAT); // MicroSec
- MyTim->setCount(0,MICROSEC_FORMAT);
- MyTim->refresh();
- MyTim->detachInterrupt();
- MyTim->attachInterrupt((void (*)(HardwareTimer *))lv_tick_handler);
- MyTim->detachInterrupt(0);
- MyTim->attachInterrupt(0,(void (*)(HardwareTimer *))lv_tick_handler);
- MyTim->resume();*/
+ /* static HardwareTimer * MyTim = new HardwareTimer(Instance);
+ MyTim->pause();
+ MyTim->setPrescaleFactor(1);
+ MyTim->setMode(0, TIMER_OUTPUT_COMPARE, NC);
+ MyTim->setOverflow(1000 * guiTickPeriod, MICROSEC_FORMAT); // MicroSec
+ MyTim->setCount(0,MICROSEC_FORMAT);
+ MyTim->refresh();
+ MyTim->detachInterrupt();
+ MyTim->attachInterrupt((void (*)(HardwareTimer *))lv_tick_handler);
+ MyTim->detachInterrupt(0);
+ MyTim->attachInterrupt(0,(void (*)(HardwareTimer *))lv_tick_handler);
+ MyTim->resume();*/
tick.start();
#endif
@@ -811,36 +817,17 @@ void guiSetup()
void IRAM_ATTR guiLoop()
{
-#ifdef STM32_CORE_VERSION_MAJOR
+#if defined(STM32F4xx)
tick.update();
-
- while(Serial.available()) {
- char ch = Serial.read();
- Serial.print(ch);
- if (ch == 13 ||ch == 10) {
- serialInputBuffer[serialInputIndex] = 0;
- if (serialInputIndex>0) dispatchCommand(serialInputBuffer);
- serialInputIndex=0;
- }else{
- if(serialInputIndex < sizeof(serialInputBuffer) - 1) {
- serialInputBuffer[serialInputIndex++] = ch;
- }
- serialInputBuffer[serialInputIndex] = 0;
- if (strcmp(serialInputBuffer,"jsonl=")==0){
- dispatchJsonl(Serial);
- serialInputIndex=0;
- }
- }
- }
#endif
- //lv_tick_handler();
+
+ // lv_tick_handler();
lv_task_handler(); /* let the GUI do its work */
guiCheckSleep();
#if TOUCH_DRIVER == 1
touch.loop();
#endif
-
}
void guiStop()
@@ -925,6 +912,7 @@ bool guiGetConfig(const JsonObject & settings)
v.set(calData[i]);
} else {
changed = true;
+ tft.setTouch(calData);
}
i++;
}
@@ -935,6 +923,8 @@ bool guiGetConfig(const JsonObject & settings)
for(uint8_t i = 0; i < 5; i++) {
array.add(calData[i]);
}
+ changed = true;
+ tft.setTouch(calData);
}
if(changed) configOutput(settings);
@@ -991,6 +981,7 @@ bool guiSetConfig(const JsonObject & settings)
oobeSetAutoCalibrate(true);
}
+ if(status) tft.setTouch(calData);
changed |= status;
}
@@ -1005,23 +996,15 @@ static void guiSetBmpHeader(uint8_t * buffer_p, int32_t data)
*buffer_p++ = (data >> 24) & 0xFF;
}
-#if defined(ARDUINO_ARCH_ESP8266)
static void guiSendBmpHeader();
-void guiTakeScreenshot(ESP8266WebServer & client)
-#endif
-#if defined(ARDUINO_ARCH_ESP32)
- static void guiSendBmpHeader();
-
-void guiTakeScreenshot(WebServer & client)
-#endif // ESP32{
-#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
+void guiTakeScreenshot()
{
- webClient = &client;
- lv_disp_t * disp = lv_disp_get_default();
+ // webClient = &client;
+ // lv_disp_t * disp = lv_disp_get_default();
- webClient->setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t));
- webClient->send(200, PSTR("image/bmp"), "");
+ // webClient->setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t));
+ // webClient->send(200, PSTR("image/bmp"), "");
guiSnapshot = 2;
guiSendBmpHeader();
@@ -1082,15 +1065,17 @@ static void guiSendBmpHeader()
buffer[70 + 0] = 0x20;
if(guiSnapshot == 1) {
+#if HASP_USE_SPIFFS > 0
size_t len = pFileOut.write(buffer, 122);
if(len != sizeof(buffer)) {
Log.warning(F("GUI: Data written does not match header size"));
} else {
Log.verbose(F("GUI: Bitmap header written"));
}
+#endif
} else if(guiSnapshot == 2) {
- if(webClient->client().write(buffer, 122) != 122) {
+ if(httpClientWrite(buffer, 122) != 122) {
Log.warning(F("GUI: Data sent does not match header size"));
} else {
Log.verbose(F("GUI: Bitmap header sent"));
@@ -1107,6 +1092,7 @@ static void guiSendBmpHeader()
* @param[in] pFileName Output binary file name.
*
**/
+#if HASP_USE_SPIFFS > 0
void guiTakeScreenshot(const char * pFileName)
{
pFileOut = SPIFFS.open(pFileName, "w");
diff --git a/src/hasp_gui.h b/src/hasp_gui.h
index f6f0618f..76166eae 100644
--- a/src/hasp_gui.h
+++ b/src/hasp_gui.h
@@ -6,15 +6,17 @@
#include "lvgl.h"
-#if defined(ARDUINO_ARCH_ESP8266)
-#include
-void guiTakeScreenshot(ESP8266WebServer & client);
-#endif
+// #if defined(ARDUINO_ARCH_ESP8266)
+// #include
+// void guiTakeScreenshot(ESP8266WebServer & client);
+// #endif
-#if defined(ARDUINO_ARCH_ESP32)
-#include
-void guiTakeScreenshot(WebServer & client);
-#endif // ESP32
+// #if defined(ARDUINO_ARCH_ESP32)
+// #include
+// void guiTakeScreenshot(WebServer & client);
+// #endif // ESP32
+
+void guiTakeScreenshot();
void guiSetup();
void guiLoop(void);
diff --git a/src/hasp_hal.cpp b/src/hasp_hal.cpp
index 83eb07c7..0348fec9 100644
--- a/src/hasp_hal.cpp
+++ b/src/hasp_hal.cpp
@@ -1,25 +1,20 @@
-#if defined(ESP32) || defined(ESP8266)
+#include "hasp_hal.h"
+#include "hasp_conf.h"
+
+#if defined(ESP8266)
#include
+#include
#endif
-#include "hasp_hal.h"
-
-#if ESP32
+#if defined(ESP32)
+#include
+#include
#include "esp_system.h"
#endif
#if defined(ARDUINO_ARCH_ESP32)
#include // needed to get the ResetInfo
-void halRestart(void)
-{
-#if defined(ESP32) || defined(ESP8266)
- ESP.restart();
-#else
- NVIC_SystemReset();
-#endif
-}
-
// Compatibility function for ESP8266 getRestInfo
String esp32ResetReason(uint8_t cpuid)
{
@@ -90,6 +85,15 @@ String esp32ResetReason(uint8_t cpuid)
}
#endif
+void halRestart(void)
+{
+#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
+ ESP.restart();
+#else
+ NVIC_SystemReset();
+#endif
+}
+
String halGetResetInfo()
{
#if defined(ARDUINO_ARCH_ESP32)
@@ -105,57 +109,6 @@ String halGetResetInfo()
#else
return "";
#endif
-}
-
- #ifdef __arm__
- // should use uinstd.h to define sbrk but Due causes a conflict
- extern "C" char* sbrk(int incr);
- #else // __ARM__
- extern char *__brkval;
- #endif // __arm__
-
- int freeMemory() {
- char top;
- #ifdef __arm__
- return &top - reinterpret_cast(sbrk(0));
- #elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
- return &top - __brkval;
- #else // __arm__
- return __brkval ? &top - __brkval : &top - __malloc_heap_start;
- #endif // __arm__
- }
-
-uint8_t halGetHeapFragmentation()
-{
-#if defined(ARDUINO_ARCH_ESP32)
- return (int8_t)(100.00f - (float)ESP.getMaxAllocHeap() * 100.00f / (float)ESP.getFreeHeap());
-#elif defined(ARDUINO_ARCH_ESP8266)
- return ESP.getHeapFragmentation();
-#else
- return 255;
-#endif
-}
-
-size_t halGetMaxFreeBlock()
-{
-#if defined(ARDUINO_ARCH_ESP32)
- return ESP.getMaxAllocHeap();
-#elif defined(ARDUINO_ARCH_ESP8266)
- return ESP.getMaxFreeBlockSize();
-#else
- return freeMemory();
-#endif
-}
-
-size_t halGetFreeHeap(void)
-{
-#if defined(ARDUINO_ARCH_ESP32)
- return ESP.getFreeHeap();
-#elif defined(ARDUINO_ARCH_ESP8266)
- return ESP.getFreeHeap();
-#else
- return 1;
-#endif
}
String halGetCoreVersion()
@@ -193,8 +146,8 @@ String halGetChipModel()
case CHIP_ESP32S2:
model += F("ESP32-S2");
break;
- #endif
- default:
+#endif
+ default:
model = F("Unknown ESP");
}
model += F(" rev");
@@ -202,4 +155,146 @@ String halGetChipModel()
#endif // ESP32
return model;
+}
+
+/*******************************/
+/* Memory Management Functions */
+
+#if defined(STM32F4xx)
+#include // for mallinfo()
+#include // for sbrk()
+
+int freeHighMemory()
+{
+ char top;
+#ifdef __arm__
+ return &top - reinterpret_cast(sbrk(0));
+#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
+ return &top - __brkval;
+#else // __arm__
+ return __brkval ? &top - __brkval : &top - __malloc_heap_start;
+#endif // __arm__
+}
+#endif
+
+/*
+extern char *fake_heap_end; // current heap start
+extern char *fake_heap_start; // current heap end
+
+char* getHeapStart() {
+ return fake_heap_start;
+}
+
+char* getHeapEnd() {
+ return (char*)sbrk(0);
+}
+
+char* getHeapLimit() {
+ return fake_heap_end;
+}
+
+int getMemUsed() { // returns the amount of used memory in bytes
+ struct mallinfo mi = mallinfo();
+ return mi.uordblks;
+}
+
+int getMemFree() { // returns the amount of free memory in bytes
+ struct mallinfo mi = mallinfo();
+ return mi.fordblks + freeHighMemory();
+} */
+
+size_t halGetMaxFreeBlock()
+{
+#if defined(ARDUINO_ARCH_ESP32)
+ return ESP.getMaxAllocHeap();
+#elif defined(ARDUINO_ARCH_ESP8266)
+ return ESP.getMaxFreeBlockSize();
+#else
+ return freeHighMemory();
+#endif
+}
+
+size_t halGetFreeHeap(void)
+{
+#if defined(ARDUINO_ARCH_ESP32)
+ return ESP.getFreeHeap();
+#elif defined(ARDUINO_ARCH_ESP8266)
+ return ESP.getFreeHeap();
+#else
+ struct mallinfo chuncks = mallinfo();
+
+ // fordblks
+ // This is the total size of memory occupied by free (not in use) chunks.
+
+ return chuncks.fordblks + freeHighMemory();
+#endif
+}
+
+uint8_t halGetHeapFragmentation()
+{
+#if defined(ARDUINO_ARCH_ESP32)
+ return (int8_t)(100.00f - (float)ESP.getMaxAllocHeap() * 100.00f / (float)ESP.getFreeHeap());
+#elif defined(ARDUINO_ARCH_ESP8266)
+ return ESP.getHeapFragmentation();
+#else
+ return (int8_t)(100.00f - (float)freeHighMemory() * 100.00f / (float)halGetFreeHeap());
+#endif
+}
+
+String halGetMacAddress(int start, const char * seperator)
+{
+ byte mac[6];
+
+#if defined(STM32F4xx)
+ uint8_t * mac_p = nullptr;
+#if USE_BUILTIN_ETHERNET > 0
+ mac_p = Ethernet.MACAddress();
+ for(uint8_t i = 0; i < 6; i++) mac[i] = *(mac_p + i);
+#else
+ Ethernet.macAddress(mac);
+#endif
+#else
+ WiFi.macAddress(mac);
+#endif
+
+ String cMac((char *)0);
+ cMac.reserve(32);
+
+ for(int i = start; i < 6; ++i) {
+ if(mac[i] < 0x10) cMac += "0";
+ cMac += String(mac[i], HEX);
+ if(i < 5) cMac += seperator;
+ }
+ cMac.toUpperCase();
+ return cMac;
+}
+
+uint16_t halGetCpuFreqMHz()
+{
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32)
+ return ESP.getCpuFreqMHz();
+#else
+ return (F_CPU / 1000 / 1000);
+#endif
+}
+
+String halFormatBytes(size_t bytes)
+{
+ String output((char *)0);
+ output.reserve(128);
+
+ if(bytes < 1024) {
+ output += bytes;
+ } else if(bytes < (1024 * 1024)) {
+ output += bytes / 1024.0;
+ output += "K";
+ } else if(bytes < (1024 * 1024 * 1024)) {
+ output += bytes / 1024.0 / 1024.0;
+ output += "M";
+ } else {
+ output += bytes / 1024.0 / 1024.0 / 1024.0;
+ output += "G";
+ }
+ output += "B";
+ return output;
}
\ No newline at end of file
diff --git a/src/hasp_hal.h b/src/hasp_hal.h
index 23ac6501..9cdbef18 100644
--- a/src/hasp_hal.h
+++ b/src/hasp_hal.h
@@ -3,12 +3,15 @@
#include
+void halRestart(void);
uint8_t halGetHeapFragmentation(void);
String halGetResetInfo(void);
size_t halGetMaxFreeBlock(void);
size_t halGetFreeHeap(void);
String halGetCoreVersion(void);
String halGetChipModel();
-void halRestart(void);
+String halGetMacAddress(int start, const char * seperator);
+uint16_t halGetCpuFreqMHz(void);
+String halFormatBytes(size_t bytes);
#endif
\ No newline at end of file
diff --git a/src/hasp_http.cpp b/src/hasp_http.cpp
index 9bb9c5ab..3cb7e0fc 100644
--- a/src/hasp_http.cpp
+++ b/src/hasp_http.cpp
@@ -1,430 +1,3 @@
-#if 0
-
-#include "Arduino.h"
-#include "ArduinoJson.h"
-#include "ArduinoLog.h"
-//#include "Update.h"
-#include "lvgl.h"
-
-#include "hasp_conf.h"
-
-#include "hasp_gui.h"
-#include "hasp_hal.h"
-#include "hasp_debug.h"
-#include "hasp_mqtt.h"
-#include "hasp_wifi.h"
-#include "hasp_spiffs.h"
-#include "hasp_config.h"
-#include "hasp_dispatch.h"
-#include "hasp.h"
-
-#ifdef ESP32
-#include
-#include
-#elif defined(ESP8266)
-#include
-#include
-#endif
-#include
-
-AsyncWebServer webServer(80);
-
-#if defined(ARDUINO_ARCH_ESP32)
-#include "SPIFFS.h"
-#endif
-#include
-#include
-
-bool httpEnable = true;
-bool webServerStarted = false;
-uint16_t httpPort = 80;
-FS * filesystem = &SPIFFS;
-File fsUploadFile;
-char httpUser[32] = "";
-char httpPassword[32] = "";
-// HTTPUpload * upload;
-#define HTTP_PAGE_SIZE (6 * 256)
-
-const char MAIN_MENU_BUTTON[] PROGMEM =
- "
";
-const char MIT_LICENSE[] PROGMEM = "MIT License";
-
-const char HTTP_DOCTYPE[] PROGMEM =
- " ";
-const char HTTP_META_GO_BACK[] PROGMEM = " ";
-const char HTTP_HEADER[] PROGMEM = "%s ";
-const char HTTP_STYLE[] PROGMEM =
- "";
-const char HTTP_SCRIPT[] PROGMEM = "";
-const char HTTP_HEADER_END[] PROGMEM =
- "";
-
-// Additional CSS style to match Hass theme
-const char HASP_STYLE[] PROGMEM =
- "";
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// URL for auto-update "version.json"
-const char UPDATE_URL[] PROGMEM = "http://haswitchplate.com/update/version.json";
-// Default link to compiled Arduino firmware image
-String espFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.ino.d1_mini.bin";
-// Default link to compiled Nextion firmware images
-String lcdFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.tft";
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-String getOption(int value, String label, bool selected)
-{
- char buffer[128];
- snprintf_P(buffer, sizeof(buffer), PSTR("
%s "), value,
- (selected ? PSTR(" selected") : ""), label.c_str());
- return buffer;
-}
-String getOption(String value, String label, bool selected)
-{
- char buffer[128];
- snprintf_P(buffer, sizeof(buffer), PSTR("
%s "), value.c_str(),
- (selected ? PSTR(" selected") : ""), label.c_str());
- return buffer;
-}
-
-bool httpIsAuthenticated(AsyncWebServerRequest * request, const String & page)
-{
- if(httpPassword[0] != '\0') { // Request HTTP auth if httpPassword is set
- if(!request->authenticate(httpUser, httpPassword)) {
- request->requestAuthentication();
- return false;
- }
- }
-
- char buffer[128];
- snprintf(buffer, sizeof(buffer), PSTR("HTTP: Sending %s page to client connected from: %s"), page.c_str(),
- request->client()->remoteIP().toString().c_str());
- debugPrintln(buffer);
- return true;
-}
-
-void webSendFooter(AsyncResponseStream * response)
-{
- response->print(F("
"));
-}
-
-void webHandleRoot(AsyncWebServerRequest * request)
-{
- if(!httpIsAuthenticated(request, F("root"))) return;
- AsyncResponseStream * response = request->beginResponseStream("text/html");
-
- String nodename((char *)0);
- nodename.reserve(128);
- nodename = httpGetNodename();
-
- response->print(F("
"));
- response->print(nodename);
- response->print(F(" "));
-
- response->print(F("
"));
- response->print(
- F("
"));
- response->print(F("
"));
-
- response->print(
- F("
"));
-
- if(SPIFFS.exists(F("/edit.htm.gz"))) {
- response->print(F("
"));
- }
-
- response->print(
- F("
"));
-
- webSendFooter(response);
- request->send(response);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void webHandleHaspConfig(AsyncWebServerRequest * request)
-{ // http://plate01/config/http
- if(!httpIsAuthenticated(request, F("config/hasp"))) return;
- AsyncResponseStream * response = request->beginResponseStream("text/html");
-
- DynamicJsonDocument settings(256);
- haspGetConfig(settings.to
());
-
- String nodename((char *)0);
- nodename.reserve(128);
- nodename = httpGetNodename();
-
- response->print(F(""));
- response->print(nodename);
- response->print(F(" "));
-
- response->print(F("
"));
-
- response->print(F(""));
-
- response->print(
- F("
"));
-
- webSendFooter(response);
- request->send(response);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void webHandleScreenshot(AsyncWebServerRequest * request)
-{ // http://plate01/screenshot
- if(!httpIsAuthenticated(request, F("screenshot"))) return;
-
- if(request->hasArg(F("q"))) {
- guiTakeScreenshot(request);
- } else {
- AsyncResponseStream * response = request->beginResponseStream("text/html");
-
- String nodename((char *)0);
- nodename.reserve(128);
- nodename = httpGetNodename();
-
- response->print(F(""));
- response->print(nodename);
- response->print(F(" "));
-
- response->print(F("
"));
- response->print(F("
"));
- // response->print( FPSTR(MAIN_MENU_BUTTON);
-
- webSendFooter(response);
- request->send(response);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void httpHandleNotFound(AsyncWebServerRequest * request)
-{ // webServer 404
- // if(handleFileRead(webServer.uri())) return;
-
- debugPrintln(String(F("HTTP: Sending 404 to client connected from: ")) + request->client()->remoteIP().toString());
-
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
-
- httpMessage += F("File Not Found\n\nURI: ");
- httpMessage += request->url();
- httpMessage += F("\nMethod: ");
- httpMessage += (request->method() == HTTP_GET) ? F("GET") : F("POST");
- httpMessage += F("\nArguments: ");
- httpMessage += request->args();
- httpMessage += "\n";
- for(uint8_t i = 0; i < request->args(); i++) {
- httpMessage += " " + request->argName(i) + ": " + request->arg(i) + "\n";
- }
- request->send(404, F("text/plain"), httpMessage);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void webHandleSaveConfig()
-{
- // if(!httpIsAuthenticated(F("saveConfig"))) return;
-
- configWriteConfig();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void webHandleFirmware()
-{
- // if(!httpIsAuthenticated(F("firmware"))) return;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void httpSetup()
-{
- if(WiFi.getMode() != WIFI_STA) {
- debugPrintln(F("HTTP: Wifi access point"));
- // webServer.on(F("/"), webHandleWifiConfig);
- } else {
-
- webServer.on(String(F("/")).c_str(), HTTP_GET, webHandleRoot);
- webServer.on(String(F("/config/hasp")).c_str(), webHandleHaspConfig);
- webServer.on(String(F("/screenshot")).c_str(), webHandleScreenshot);
-
- webServer.onNotFound(httpHandleNotFound);
-
- webServer.begin();
-
- httpReconnect();
- debugPrintln(F("HTTP: Setup Complete"));
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void httpReconnect()
-{
- if(!httpEnable) return;
-
- if(webServerStarted) {
- webServer.end();
- webServerStarted = false;
- debugPrintln(F("HTTP: Server stoped"));
- } else if(WiFi.status() == WL_CONNECTED || WiFi.getMode() != WIFI_STA) {
-
- /*
- if(WiFi.getMode() != WIFI_STA) {
- webServer.on(F("/"), webHandleWifiConfig);
- webServer.on(F("/config"), webHandleConfig);
- webServer.onNotFound(httpHandleNotFound);
- } else {
- }
- */
- webServer.begin();
- webServerStarted = true;
-
- debugPrintln(String(F("HTTP: Server started @ http://")) +
- (WiFi.getMode() != WIFI_STA ? WiFi.softAPIP().toString() : WiFi.localIP().toString()));
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void httpLoop()
-{
- // if(httpEnable) webServer.handleClient();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void httpEverySecond()
-{
- if(httpEnable && !webServerStarted) httpReconnect();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-bool httpGetConfig(const JsonObject & settings)
-{
- settings[FPSTR(F_CONFIG_ENABLE)] = httpEnable;
- settings[FPSTR(F_CONFIG_PORT)] = httpPort;
- settings[FPSTR(F_CONFIG_USER)] = httpUser;
- settings[FPSTR(F_CONFIG_PASS)] = httpPassword;
-
- configOutput(settings);
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-bool httpSetConfig(const JsonObject & settings)
-{
- configOutput(settings);
- bool changed = false;
-
- changed |= configSet(httpPort, settings[FPSTR(F_CONFIG_PORT)], PSTR("httpPort"));
-
- if(!settings[FPSTR(F_CONFIG_USER)].isNull()) {
- changed |= strcmp(httpUser, settings[FPSTR(F_CONFIG_USER)]) != 0;
- strncpy(httpUser, settings[FPSTR(F_CONFIG_USER)], sizeof(httpUser));
- }
-
- if(!settings[FPSTR(F_CONFIG_PASS)].isNull()) {
- changed |= strcmp(httpPassword, settings[FPSTR(F_CONFIG_PASS)]) != 0;
- strncpy(httpPassword, settings[FPSTR(F_CONFIG_PASS)], sizeof(httpPassword));
- }
-
- return changed;
-}
-
-#else
-
//#include "webServer.h"
#include "Arduino.h"
#include "ArduinoJson.h"
@@ -432,7 +5,7 @@ bool httpSetConfig(const JsonObject & settings)
#include "lvgl.h"
#include "StringStream.h"
-#ifdef ESP32
+#if defined(ARDUINO_ARCH_ESP32)
#include "Update.h"
#endif
@@ -457,18 +30,26 @@ bool httpSetConfig(const JsonObject & settings)
#include
#endif
-#if HASP_USE_HTTP>0
+#if HASP_USE_HTTP > 0
bool httpEnable = true;
bool webServerStarted = false;
uint16_t httpPort = 80;
-FS * filesystem = &SPIFFS;
+
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
+FS * filesystem = &SPIFFS;
File fsUploadFile;
+#endif
+
char httpUser[32] = "";
char httpPassword[32] = "";
-HTTPUpload * upload;
#define HTTP_PAGE_SIZE (6 * 256)
+#if defined(STM32F4xx)
+#include
+EthernetWebServer webServer(80);
+#endif
+
#if defined(ARDUINO_ARCH_ESP8266)
#include
ESP8266WebServer webServer(80);
@@ -477,9 +58,10 @@ ESP8266WebServer webServer(80);
#if defined(ARDUINO_ARCH_ESP32)
#include
WebServer webServer(80);
-
#endif // ESP32
+HTTPUpload * upload;
+
const char MAIN_MENU_BUTTON[] PROGMEM =
"
";
const char MIT_LICENSE[] PROGMEM = "MIT License";
@@ -528,7 +110,6 @@ String lcdFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.tft";
#if HASP_USE_MQTT > 0
extern char mqttNodeName[16];
-extern char mqttNodeName[16];
#else
char mqttNodeName[3] = "na";
#endif
@@ -551,10 +132,14 @@ bool httpIsAuthenticated(const __FlashStringHelper * page)
}
}
- {
- Log.verbose(F("HTTP: Sending %s page to client connected from: %s"), page,
- webServer.client().remoteIP().toString().c_str());
- }
+#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
+ Log.verbose(F("HTTP: Sending %s page to client connected from: %s"), page,
+ webServer.client().remoteIP().toString().c_str());
+#else
+ // Log.verbose(F("HTTP: Sending %s page to client connected from: %s"), page,
+ // String(webServer.client().remoteIP()).c_str());
+#endif
+
return true;
}
@@ -577,72 +162,100 @@ void webSendFooter()
char buffer[128];
snprintf_P(buffer, sizeof(buffer), PSTR("%u.%u.%u"), HASP_VERSION_MAJOR, HASP_VERSION_MINOR, HASP_VERSION_REVISION);
+#if defined(STM32F4xx)
+ webServer.sendContent(HTTP_END);
+ webServer.sendContent(buffer);
+ webServer.sendContent(HTTP_FOOTER);
+#else
webServer.sendContent_P(HTTP_END);
webServer.sendContent(buffer);
webServer.sendContent_P(HTTP_FOOTER);
+#endif
}
void webSendPage(char * nodename, uint32_t httpdatalength, bool gohome = false)
{
- char buffer[64];
- snprintf_P(buffer, sizeof(buffer), PSTR("%u.%u.%u"), HASP_VERSION_MAJOR, HASP_VERSION_MINOR, HASP_VERSION_REVISION);
+ {
+ char buffer[64];
+ snprintf_P(buffer, sizeof(buffer), PSTR("%u.%u.%u"), HASP_VERSION_MAJOR, HASP_VERSION_MINOR,
+ HASP_VERSION_REVISION);
- /* Calculate Content Length upfront */
- uint16_t contentLength = strlen(buffer); // verion length
- contentLength += sizeof(HTTP_DOCTYPE) - 1;
- contentLength += sizeof(HTTP_HEADER) - 1 - 2 + strlen(nodename);
- contentLength += sizeof(HTTP_SCRIPT) - 1;
- contentLength += sizeof(HTTP_STYLE) - 1;
- contentLength += sizeof(HASP_STYLE) - 1;
- if(gohome) contentLength += sizeof(HTTP_META_GO_BACK) - 1;
- contentLength += sizeof(HTTP_HEADER_END) - 1;
- contentLength += sizeof(HTTP_END) - 1;
- contentLength += sizeof(HTTP_FOOTER) - 1;
+ /* Calculate Content Length upfront */
+ uint16_t contentLength = strlen(buffer); // verion length
+ contentLength += sizeof(HTTP_DOCTYPE) - 1;
+ contentLength += sizeof(HTTP_HEADER) - 1 - 2 + strlen(nodename);
+ contentLength += sizeof(HTTP_SCRIPT) - 1;
+ contentLength += sizeof(HTTP_STYLE) - 1;
+ contentLength += sizeof(HASP_STYLE) - 1;
+ if(gohome) contentLength += sizeof(HTTP_META_GO_BACK) - 1;
+ contentLength += sizeof(HTTP_HEADER_END) - 1;
+ contentLength += sizeof(HTTP_END) - 1;
+ contentLength += sizeof(HTTP_FOOTER) - 1;
- if(httpdatalength > HTTP_PAGE_SIZE) {
- Log.warning(F("HTTP: Sending page with %u static and %u dynamic bytes"), contentLength, httpdatalength);
+ if(httpdatalength > HTTP_PAGE_SIZE) {
+ Log.warning(F("HTTP: Sending page with %u static and %u dynamic bytes"), contentLength, httpdatalength);
+ }
+
+ webServer.setContentLength(contentLength + httpdatalength);
+#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
+ webServer.send_P(200, PSTR("text/html"), HTTP_DOCTYPE); // 122
+#else
+ webServer.send(200, ("text/html"), HTTP_DOCTYPE); // 122
+#endif
+
+ sprintf_P(buffer, HTTP_HEADER, nodename);
+ webServer.sendContent(buffer); // 17-2+len
}
- webServer.setContentLength(contentLength + httpdatalength);
- webServer.send_P(200, PSTR("text/html"), HTTP_DOCTYPE); // 122
- sprintf_P(buffer, HTTP_HEADER, nodename);
- webServer.sendContent(buffer); // 17-2+len
+#if defined(STM32F4xx)
+ webServer.sendContent(HTTP_SCRIPT); // 131
+ webServer.sendContent(HTTP_STYLE); // 487
+ webServer.sendContent(HASP_STYLE); // 145
+ if(gohome) webServer.sendContent(HTTP_META_GO_BACK); // 47
+ webServer.sendContent(HTTP_HEADER_END); // 80
+#else
webServer.sendContent_P(HTTP_SCRIPT); // 131
webServer.sendContent_P(HTTP_STYLE); // 487
webServer.sendContent_P(HASP_STYLE); // 145
if(gohome) webServer.sendContent_P(HTTP_META_GO_BACK); // 47
webServer.sendContent_P(HTTP_HEADER_END); // 80
+#endif
}
void webHandleRoot()
{
if(!httpIsAuthenticated(F("root"))) return;
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("
");
- httpMessage += F("
");
- httpMessage +=
- PSTR("
");
+ httpMessage += F("
");
+ httpMessage +=
+ F("
");
+ httpMessage +=
+ PSTR("
");
- httpMessage +=
- F("
");
+ httpMessage +=
+ F("
");
- if(SPIFFS.exists(F("/edit.htm.gz"))) {
- httpMessage += F(
- "
");
+#if HASP_USE_SPIFFS > 0
+ if(SPIFFS.exists(F("/edit.htm.gz"))) {
+ httpMessage += F("
");
+ }
+#endif
+
+ httpMessage +=
+ F("
");
+
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
}
-
- httpMessage +=
- F("
");
-
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ // httpMessage.clear();
webSendFooter();
}
@@ -651,16 +264,18 @@ void httpHandleReboot()
{ // http://plate01/reboot
if(!httpIsAuthenticated(F("reboot"))) return;
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
- httpMessage = F("Rebooting Device");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
+ httpMessage = F("Rebooting Device");
- webSendPage(httpGetNodename(), httpMessage.length(), true);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), true);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
delay(200);
@@ -692,30 +307,36 @@ void webHandleScreenshot()
}
if(webServer.hasArg(F("q"))) {
- guiTakeScreenshot(webServer);
+ lv_disp_t * disp = lv_disp_get_default();
+ webServer.setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t));
+ webServer.send(200, PSTR("image/bmp"), "");
+ guiTakeScreenshot();
+ webServer.client().stop();
+
} else {
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ httpMessage +=
+ F("");
+ httpMessage += F("
");
+ httpMessage += F(
+ "
");
+ httpMessage += F("
");
+ httpMessage += F("
");
+ httpMessage += FPSTR(MAIN_MENU_BUTTON);
- httpMessage +=
- F("");
- httpMessage += F("
");
- httpMessage +=
- F("
");
- httpMessage += F("
");
- httpMessage += F("
");
- httpMessage += FPSTR(MAIN_MENU_BUTTON);
-
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
}
}
@@ -726,44 +347,47 @@ void webHandleAbout()
{ // http://plate01/about
if(!httpIsAuthenticated(F("about"))) return;
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("
HASP OpenHardware edition Copyright© 2020 Francis Van Roie ");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("Based on the previous work of the following open source developers.
");
- httpMessage += F("
HASwitchPlate Copyright© 2019 Allen Derusha allen@derusha.org");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage +=
- F("
LittlevGL Copyright© 2016 Gábor Kiss-VámosiCopyright© 2019 "
- "LittlevGL");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("
zi Font Engine Copyright© 2020 Francis Van Roie");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("
TFT_eSPI Library Copyright© 2020 Bodmer (https://github.com/Bodmer) All "
- "rights reserved.FreeBSD License");
- httpMessage +=
- F("includes parts from the Adafruit_GFX library Copyright© 2012 Adafruit Industries. "
- "All rights reservedBSD License
");
- httpMessage += F("
ArduinoJson Copyright© 2014-2020 Benoit BLANCHON");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("
PubSubClient Copyright© 2008-2015 Nicholas O'Leary");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("
ArduinoLog Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, "
- "dhylands, Josha blemasle, mfalkvidd");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("
Syslog Copyright© 2016 Martin Sloup");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("
QR Code generator Copyright© Project Nayuki");
- httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("
AceButton Copyright© 2018 Brian T. Park");
- httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("
HASP OpenHardware edition Copyright© 2020 Francis Van Roie ");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("Based on the previous work of the following open source developers.
");
+ httpMessage += F("
HASwitchPlate Copyright© 2019 Allen Derusha allen@derusha.org");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage +=
+ F("
LittlevGL Copyright© 2016 Gábor Kiss-VámosiCopyright© 2019 "
+ "LittlevGL");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("
zi Font Engine Copyright© 2020 Francis Van Roie");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("
TFT_eSPI Library Copyright© 2020 Bodmer (https://github.com/Bodmer) All "
+ "rights reserved.FreeBSD License");
+ httpMessage +=
+ F("includes parts from the Adafruit_GFX library Copyright© 2012 Adafruit Industries. "
+ "All rights reservedBSD License
");
+ httpMessage += F("
ArduinoJson Copyright© 2014-2020 Benoit BLANCHON");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("
PubSubClient Copyright© 2008-2015 Nicholas O'Leary");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage +=
+ F("
ArduinoLog Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, "
+ "dhylands, Josha blemasle, mfalkvidd");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("
Syslog Copyright© 2016 Martin Sloup");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("
QR Code generator Copyright© Project Nayuki");
+ httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("
AceButton Copyright© 2018 Brian T. Park");
+ httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += FPSTR(MAIN_MENU_BUTTON);
+ httpMessage += FPSTR(MAIN_MENU_BUTTON);
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
}
@@ -772,144 +396,151 @@ void webHandleInfo()
{ // http://plate01/
if(!httpIsAuthenticated(F("info"))) return;
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- /* HASP Stats */
- httpMessage += F("HASP Version: ");
- httpMessage += String(haspGetVersion());
- httpMessage += F("Build DateTime: ");
- httpMessage += __DATE__;
- httpMessage += F(" ");
- httpMessage += __TIME__;
- httpMessage += F(" CETUptime: ");
+ /* HASP Stats */
+ httpMessage += F("HASP Version: ");
+ httpMessage += String(haspGetVersion());
+ httpMessage += F("Build DateTime: ");
+ httpMessage += __DATE__;
+ httpMessage += F(" ");
+ httpMessage += __TIME__;
+ httpMessage += F(" CETUptime: ");
- unsigned long time = millis() / 1000;
- uint16_t day = time / 86400;
- time = time % 86400;
- uint8_t hour = time / 3600;
- time = time % 3600;
- uint8_t min = time / 60;
- time = time % 60;
- uint8_t sec = time;
+ unsigned long time = millis() / 1000;
+ uint16_t day = time / 86400;
+ time = time % 86400;
+ uint8_t hour = time / 3600;
+ time = time % 3600;
+ uint8_t min = time / 60;
+ time = time % 60;
+ uint8_t sec = time;
- if(day > 0) {
- httpMessage += String(day);
- httpMessage += F("d ");
- }
- if(day > 0 || hour > 0) {
- httpMessage += String(hour);
- httpMessage += F("h ");
- }
- if(day > 0 || hour > 0 || min > 0) {
- httpMessage += String(min);
- httpMessage += F("m ");
- }
- httpMessage += String(sec);
- httpMessage += F("s");
+ if(day > 0) {
+ httpMessage += String(day);
+ httpMessage += F("d ");
+ }
+ if(day > 0 || hour > 0) {
+ httpMessage += String(hour);
+ httpMessage += F("h ");
+ }
+ if(day > 0 || hour > 0 || min > 0) {
+ httpMessage += String(min);
+ httpMessage += F("m ");
+ }
+ httpMessage += String(sec);
+ httpMessage += F("s");
- httpMessage += F("Free Memory: ");
- httpMessage += spiffsFormatBytes(ESP.getFreeHeap());
- httpMessage += F("Memory Fragmentation: ");
- httpMessage += String(halGetHeapFragmentation());
+ httpMessage += F("Free Memory: ");
+ httpMessage += halFormatBytes(halGetFreeHeap());
+ httpMessage += F("Memory Fragmentation: ");
+ httpMessage += String(halGetHeapFragmentation());
- /* LVGL Stats */
- lv_mem_monitor_t mem_mon;
- lv_mem_monitor(&mem_mon);
- httpMessage += F("LVGL Memory: ");
- httpMessage += spiffsFormatBytes(mem_mon.total_size);
- httpMessage += F("LVGL Free: ");
- httpMessage += spiffsFormatBytes(mem_mon.free_size);
- httpMessage += F("LVGL Fragmentation: ");
- httpMessage += mem_mon.frag_pct;
+ /* LVGL Stats */
+ lv_mem_monitor_t mem_mon;
+ lv_mem_monitor(&mem_mon);
+ httpMessage += F("
LVGL Memory: ");
+ httpMessage += halFormatBytes(mem_mon.total_size);
+ httpMessage += F("LVGL Free: ");
+ httpMessage += halFormatBytes(mem_mon.free_size);
+ httpMessage += F("LVGL Fragmentation: ");
+ httpMessage += mem_mon.frag_pct;
- // httpMessage += F("LCD Model: ")) + String(LV_HASP_HOR_RES_MAX) + " x " +
- // String(LV_HASP_VER_RES_MAX); httpMessage += F("LCD Version: ")) +
- // String(lcdVersion);
- httpMessage += F("
LCD Active Page: ");
- httpMessage += String(haspGetPage());
+ // httpMessage += F("LCD Model: ")) + String(LV_HASP_HOR_RES_MAX) + " x " +
+ // String(LV_HASP_VER_RES_MAX); httpMessage += F("LCD Version: ")) +
+ // String(lcdVersion);
+ httpMessage += F("
LCD Active Page: ");
+ httpMessage += String(haspGetPage());
- /* Wifi Stats */
- httpMessage += F("
SSID: ");
- httpMessage += String(WiFi.SSID());
- httpMessage += F("Signal Strength: ");
+ /* Wifi Stats */
+#if HASP_USE_WIFI > 0
+ httpMessage += F("
SSID: ");
+ httpMessage += String(WiFi.SSID());
+ httpMessage += F("Signal Strength: ");
- int8_t rssi = WiFi.RSSI();
- httpMessage += String(rssi);
- httpMessage += F("dBm (");
+ int8_t rssi = WiFi.RSSI();
+ httpMessage += String(rssi);
+ httpMessage += F("dBm (");
- if(rssi >= -50) {
- httpMessage += F("Excellent)");
- } else if(rssi >= -60) {
- httpMessage += F("Good)");
- } else if(rssi >= -70) {
- httpMessage += F("Fair)");
- } else if(rssi >= -80) {
- httpMessage += F("Weak)");
- } else {
- httpMessage += F("Very Bad)");
- }
+ if(rssi >= -50) {
+ httpMessage += F("Excellent)");
+ } else if(rssi >= -60) {
+ httpMessage += F("Good)");
+ } else if(rssi >= -70) {
+ httpMessage += F("Fair)");
+ } else if(rssi >= -80) {
+ httpMessage += F("Weak)");
+ } else {
+ httpMessage += F("Very Bad)");
+ }
- httpMessage += F("IP Address: ");
- httpMessage += String(WiFi.localIP().toString());
- httpMessage += F("Gateway: ");
- httpMessage += String(WiFi.gatewayIP().toString());
- httpMessage += F("DNS Server: ");
- httpMessage += String(WiFi.dnsIP().toString());
- httpMessage += F("MAC Address: ");
- httpMessage += String(WiFi.macAddress());
+ httpMessage += F("IP Address: ");
+ httpMessage += String(WiFi.localIP().toString());
+ httpMessage += F("Gateway: ");
+ httpMessage += String(WiFi.gatewayIP().toString());
+ httpMessage += F("DNS Server: ");
+ httpMessage += String(WiFi.dnsIP().toString());
+ httpMessage += F("MAC Address: ");
+ httpMessage += String(WiFi.macAddress());
+#endif
/* Mqtt Stats */
#if HASP_USE_MQTT > 0
- httpMessage += F("
MQTT Status: ");
- if(mqttIsConnected()) { // Check MQTT connection
- httpMessage += F("Connected");
- } else {
- httpMessage += F("Disconnected , return code: ");
- // +String(mqttClient.returnCode());
- }
- httpMessage += F("MQTT ClientID: ");
+ httpMessage += F("
MQTT Status: ");
+ if(mqttIsConnected()) { // Check MQTT connection
+ httpMessage += F("Connected");
+ } else {
+ httpMessage += F("Disconnected , return code: ");
+ // +String(mqttClient.returnCode());
+ }
+ httpMessage += F("MQTT ClientID: ");
- {
- char mqttClientId[64];
- byte mac[6];
- WiFi.macAddress(mac);
- snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%2x%2x%2x"), mqttNodeName, mac[3], mac[4], mac[5]);
- httpMessage += mqttClientId;
- }
+ {
+ char mqttClientId[64];
+ String mac = halGetMacAddress(3, "");
+ mac.toLowerCase();
+ snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%s"), mqttNodeName, mac.c_str());
+ httpMessage += mqttClientId;
+ }
+#endif // MQTT
+
+ /* ESP Stats */
+ httpMessage += F("
MCU Model: ");
+ httpMessage += halGetChipModel();
+ httpMessage += F("CPU Frequency: ");
+ httpMessage += String(halGetCpuFreqMHz());
+
+#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
+ httpMessage += F("MHzFlash Chip Size: ");
+ httpMessage += halFormatBytes(ESP.getFlashChipSize());
+ httpMessage += F("Program Size: ");
+ httpMessage += halFormatBytes(ESP.getSketchSize());
+ httpMessage += F("Free Program Space: ");
+ httpMessage += halFormatBytes(ESP.getFreeSketchSpace());
#endif
- /* ESP Stats */
- httpMessage += F("
MCU Model: ");
- httpMessage += halGetChipModel();
- httpMessage += F("CPU Frequency: ");
- httpMessage += String(ESP.getCpuFreqMHz());
- httpMessage += F("MHzFlash Chip Size: ");
- httpMessage += spiffsFormatBytes(ESP.getFlashChipSize());
- httpMessage += F("Program Size: ");
- httpMessage += spiffsFormatBytes(ESP.getSketchSize());
- httpMessage += F("Free Program Space: ");
- httpMessage += spiffsFormatBytes(ESP.getFreeSketchSpace());
+ //#if defined(ARDUINO_ARCH_ESP32)
+ // httpMessage += F("ESP SDK version: ");
+ // httpMessage += String(ESP.getSdkVersion());
+ //#else
+ httpMessage += F("Core version: ");
+ httpMessage += String(halGetCoreVersion());
+ //#endif
+ httpMessage += F("Last Reset: ");
+ httpMessage += halGetResetInfo();
-#if defined(ARDUINO_ARCH_ESP32)
- httpMessage += F("ESP SDK version: ");
- httpMessage += String(ESP.getSdkVersion());
-#else
- httpMessage += F("ESP Core version: ");
- httpMessage += String(ESP.getCoreVersion());
-#endif
- httpMessage += F("Last Reset: ");
- httpMessage += halGetResetInfo();
+ httpMessage += FPSTR(MAIN_MENU_BUTTON);
- httpMessage += FPSTR(MAIN_MENU_BUTTON);
-
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
}
@@ -969,30 +600,6 @@ String getContentType(String filename)
return encodedString;
} */
-bool handleFileRead(String path)
-{
- if(!httpIsAuthenticated(F("fileread"))) return false;
-
- path = webServer.urlDecode(path).substring(0, 31);
- if(path.endsWith("/")) {
- path += F("index.htm");
- }
- String pathWithGz = path + F(".gz");
- if(filesystem->exists(pathWithGz) || filesystem->exists(path)) {
- if(filesystem->exists(pathWithGz)) path += F(".gz");
-
- File file = filesystem->open(path, "r");
- String contentType = getContentType(path);
- if(path == F("/edit.htm.gz")) {
- contentType = F("text/html");
- }
- webServer.streamFile(file, contentType);
- file.close();
- return true;
- }
- return false;
-}
-
static unsigned long htppLastLoopTime = 0;
void webUploadProgress()
{
@@ -1002,6 +609,7 @@ void webUploadProgress()
}
}
+#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
void webUpdatePrintError()
{
String output((char *)0);
@@ -1015,16 +623,18 @@ void webUpdateReboot()
{
Log.notice(F("Update Success: %u bytes received. Rebooting..."), upload->totalSize);
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("
");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
- httpMessage += F("Upload complete. Rebooting device, please wait... ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
+ httpMessage += F("Upload complete. Rebooting device, please wait... ");
- webSendPage(httpGetNodename(), httpMessage.length(), true);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), true);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
delay(250);
@@ -1059,6 +669,32 @@ void webHandleFirmwareUpdate()
}
}
}
+#endif
+
+#if HASP_USE_SPIFFS > 0
+bool handleFileRead(String path)
+{
+ if(!httpIsAuthenticated(F("fileread"))) return false;
+
+ path = webServer.urlDecode(path).substring(0, 31);
+ if(path.endsWith("/")) {
+ path += F("index.htm");
+ }
+ String pathWithGz = path + F(".gz");
+ if(filesystem->exists(pathWithGz) || filesystem->exists(path)) {
+ if(filesystem->exists(pathWithGz)) path += F(".gz");
+
+ File file = filesystem->open(path, "r");
+ String contentType = getContentType(path);
+ if(path == F("/edit.htm.gz")) {
+ contentType = F("text/html");
+ }
+ webServer.streamFile(file, contentType);
+ file.close();
+ return true;
+ }
+ return false;
+}
void handleFileUpload()
{
@@ -1123,7 +759,7 @@ void handleFileDelete()
}
filesystem->remove(path);
webServer.send_P(200, mimetype, PSTR(""));
- path.clear();
+ // path.clear();
}
void handleFileCreate()
@@ -1188,7 +824,8 @@ void handleFileList()
file = root.openNextFile();
}
output += "]";
-#else
+ webServer.send(200, PSTR("text/json"), output);
+#elif defined(ARDUINO_ARCH_ESP8266)
Dir dir = filesystem->openDir(path);
String output = "[";
while(dir.next()) {
@@ -1209,9 +846,10 @@ void handleFileList()
entry.close();
}
output += "]";
-#endif
webServer.send(200, PSTR("text/json"), output);
+#endif
}
+#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
void webHandleConfig()
@@ -1245,51 +883,65 @@ void webHandleConfig()
// Password might have changed
if(!httpIsAuthenticated(F("config"))) return;
+#if HASP_USE_WIFI > 0
} else if(save == String(PSTR("wifi"))) {
wifiSetConfig(settings.as());
+#endif
}
}
}
+// Reboot after saving wifi config in AP mode
+#if HASP_USE_WIFI > 0
if(WiFi.getMode() != WIFI_STA) {
httpHandleReboot();
}
-
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
-
- httpMessage +=
- F("
");
-
-#if HASP_USE_MQTT > 0
- httpMessage +=
- F("
");
#endif
- httpMessage +=
- F("
");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage +=
- F("
");
+#if HASP_USE_WIFI > 0
+ httpMessage +=
+ F("
");
+#endif
- httpMessage +=
- F("
");
+#if HASP_USE_MQTT > 0
+ httpMessage +=
+ F("
");
+#endif
- httpMessage +=
- F("
");
+ httpMessage +=
+ F("
");
- httpMessage += F("
");
+ httpMessage +=
+ F("
");
- httpMessage += FPSTR(MAIN_MENU_BUTTON);
- ;
+ httpMessage +=
+ F("
");
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+#if HASP_USE_GPIO > 0
+ httpMessage +=
+ F("
");
+#endif
+
+ httpMessage +=
+ F("
");
+
+ httpMessage += F("
");
+
+ httpMessage += FPSTR(MAIN_MENU_BUTTON);
+ ;
+
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
}
@@ -1302,41 +954,43 @@ void webHandleMqttConfig()
DynamicJsonDocument settings(256);
mqttGetConfig(settings.to());
- // char buffer[128];
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ // char buffer[128];
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("");
- httpMessage +=
- PSTR("
");
+ httpMessage += F("'>Save Settings
");
+ httpMessage +=
+ PSTR("
");
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
}
#endif
@@ -1346,70 +1000,71 @@ void webHandleGuiConfig()
{ // http://plate01/config/wifi
if(!httpIsAuthenticated(F("config/gui"))) return;
- DynamicJsonDocument settings(256);
- guiGetConfig(settings.to());
+ {
+ DynamicJsonDocument settings(256);
+ guiGetConfig(settings.to());
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("");
+ httpMessage += F("Save Settings
");
- httpMessage += PSTR("
");
+ httpMessage += PSTR("
");
- httpMessage +=
- PSTR("
");
+ httpMessage +=
+ PSTR("
");
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
webSendFooter();
if(webServer.hasArg(F("action"))) dispatchCommand(webServer.arg(F("action")));
@@ -1441,10 +1096,12 @@ void webHandleWifiConfig()
}
httpMessage += F("'>Save Settings
");
+#if HASP_USE_WIFI > 0
if(WiFi.getMode() == WIFI_STA) {
httpMessage +=
PSTR("
");
}
+#endif
webSendPage(httpGetNodename(), httpMessage.length(), false);
webServer.sendContent(httpMessage);
@@ -1459,93 +1116,138 @@ void webHandleHttpConfig()
{ // http://plate01/config/http
if(!httpIsAuthenticated(F("config/http"))) return;
- DynamicJsonDocument settings(256);
- httpGetConfig(settings.to());
+ {
+ DynamicJsonDocument settings(256);
+ httpGetConfig(settings.to());
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("");
+
+ httpMessage +=
+ PSTR("
");
+
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
}
- httpMessage += F("'>Save Settings
");
-
- httpMessage +=
- PSTR("
");
-
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ // httpMessage.clear();
webSendFooter();
}
#endif
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void webHandleGpioConfig()
+{ // http://plate01/config/gpio
+ if(!httpIsAuthenticated(F("config/gpio"))) return;
+
+ DynamicJsonDocument settings(256);
+ debugGetConfig(settings.to());
+
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
+
+ httpMessage += F("");
+
+ httpMessage +=
+ PSTR("
");
+
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
+ webSendFooter();
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
void webHandleDebugConfig()
-{ // http://plate01/config/http
+{ // http://plate01/config/debug
if(!httpIsAuthenticated(F("config/debug"))) return;
DynamicJsonDocument settings(256);
debugGetConfig(settings.to());
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("");
+
+ httpMessage +=
+ PSTR("
");
+
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
}
-
- httpMessage += F("Syslog Protocol () == 0) httpMessage += F(" checked");
- httpMessage += F(">IETF (RFC 5424) () == 1) httpMessage += F(" checked");
- httpMessage += F(">BSD (RFC 3164)");
-
- httpMessage += F("Save Settings
");
-
- httpMessage +=
- PSTR("
");
-
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ // httpMessage.clear();
webSendFooter();
}
@@ -1557,105 +1259,114 @@ void webHandleHaspConfig()
DynamicJsonDocument settings(256);
haspGetConfig(settings.to());
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("
");
+ httpMessage += F("
");
- httpMessage += F("");
+ httpMessage += F("Save Settings
");
- httpMessage += F("
Configuration ");
+ httpMessage +=
+ F("
Configuration ");
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void httpHandleNotFound()
{ // webServer 404
+#if HASP_USE_SPIFFS > 0
if(handleFileRead(webServer.uri())) return;
+#endif
+#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
Log.notice(F("HTTP: Sending 404 to client connected from: %s"), webServer.client().remoteIP().toString().c_str());
+#else
+ // Log.notice(F("HTTP: Sending 404 to client connected from: %s"), String(webServer.client().remoteIP()).c_str());
+#endif
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -1686,25 +1397,27 @@ void webHandleFirmware()
{
if(!httpIsAuthenticated(F("firmware"))) return;
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("
");
- httpMessage += F("Update Firmware ");
+ httpMessage += F("
");
+ httpMessage += F("Update Firmware ");
- httpMessage += F("
");
- httpMessage += F("Replace Filesystem Image ");
+ httpMessage += F("
");
+ httpMessage += F("Replace Filesystem Image ");
- httpMessage += FPSTR(MAIN_MENU_BUTTON);
+ httpMessage += FPSTR(MAIN_MENU_BUTTON);
- webSendPage(httpGetNodename(), httpMessage.length(), false);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ }
+ // httpMessage.clear();
webSendFooter();
}
@@ -1713,18 +1426,20 @@ void httpHandleEspFirmware()
{ // http://plate01/espfirmware
if(!httpIsAuthenticated(F("espfirmware"))) return;
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- httpMessage += F("ESP update
Updating ESP firmware from: ");
- httpMessage += webServer.arg("espFirmware");
+ httpMessage += F("ESP update
Updating ESP firmware from: ");
+ httpMessage += webServer.arg("espFirmware");
- webSendPage(httpGetNodename(), httpMessage.length(), true);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ webSendPage(httpGetNodename(), httpMessage.length(), true);
+ webServer.sendContent(httpMessage);
+ // httpMessage.clear();
+ }
webSendFooter();
Log.notice(F("HTTP: Attempting ESP firmware update from: %s"), webServer.arg("espFirmware").c_str());
@@ -1738,36 +1453,42 @@ void httpHandleResetConfig()
bool resetConfirmed = webServer.arg(F("confirm")) == F("yes");
- String httpMessage((char *)0);
- httpMessage.reserve(HTTP_PAGE_SIZE);
- httpMessage += F("");
- httpMessage += httpGetNodename();
- httpMessage += F(" ");
+ {
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += httpGetNodename();
+ httpMessage += F(" ");
- if(resetConfirmed) { // User has confirmed, so reset everything
- bool formatted = SPIFFS.format();
- if(formatted) {
- httpMessage += F("Resetting all saved settings and restarting device into WiFi AP mode ");
+ if(resetConfirmed) { // User has confirmed, so reset everything
+#if HASP_USE_SPIFFS > 0
+ bool formatted = SPIFFS.format();
+ if(formatted) {
+ httpMessage += F("Resetting all saved settings and restarting device into WiFi AP mode ");
+ } else {
+ httpMessage += F("Failed to format the internal flash partition ");
+ resetConfirmed = false;
+ }
+#endif
} else {
- httpMessage += F("Failed to format the internal flash partition ");
- resetConfirmed = false;
+ httpMessage +=
+ F("Warning This process will reset all settings to the default values. The internal flash "
+ "will "
+ "be erased and the device is restarted. You may need to connect to the WiFi AP displayed on the "
+ "panel to "
+ "re-configure the device before accessing it again. ALL FILES WILL BE LOST!"
+ ""
+ "Reset All Settings "
+ " ");
+
+ httpMessage +=
+ PSTR("
Configuration ");
}
- } else {
- httpMessage +=
- F("Warning This process will reset all settings to the default values. The internal flash will "
- "be erased and the device is restarted. You may need to connect to the WiFi AP displayed on the panel to "
- "re-configure the device before accessing it again. ALL FILES WILL BE LOST!"
- ""
- "Reset All Settings "
- " ");
- httpMessage +=
- PSTR("
Configuration ");
+ webSendPage(httpGetNodename(), httpMessage.length(), resetConfirmed);
+ webServer.sendContent(httpMessage);
}
-
- webSendPage(httpGetNodename(), httpMessage.length(), resetConfirmed);
- webServer.sendContent(httpMessage);
- httpMessage.clear();
+ // httpMessage.clear();
webSendFooter();
if(resetConfirmed) {
@@ -1781,8 +1502,14 @@ void webStart()
{
webServer.begin();
webServerStarted = true;
+#if HASP_USE_WIFI > 0
Log.notice(F("HTTP: Server started @ http://%s"),
(WiFi.getMode() != WIFI_STA ? WiFi.softAPIP().toString().c_str() : WiFi.localIP().toString().c_str()));
+#else
+ IPAddress ip;
+ ip = Ethernet.localIP();
+ Log.notice(F("HTTP: Server started @ http://%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
+#endif
}
void webStop()
@@ -1797,10 +1524,12 @@ void httpSetup()
{
// httpSetConfig(settings);
+#if HASP_USE_WIFI > 0
if(WiFi.getMode() != WIFI_STA) {
Log.notice(F("HTTP: Wifi access point"));
webServer.on(F("/"), webHandleWifiConfig);
} else {
+#endif
webServer.on(F("/page/"), []() {
String pageid = webServer.arg(F("page"));
@@ -1808,6 +1537,7 @@ void httpSetup()
haspSetPage(pageid.toInt());
});
+#if HASP_USE_SPIFFS > 0
webServer.on(F("/list"), HTTP_GET, handleFileList);
// load editor
webServer.on(F("/edit"), HTTP_GET, []() {
@@ -1823,6 +1553,8 @@ void httpSetup()
// second callback handles file uploads at that location
webServer.on(
F("/edit"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, handleFileUpload);
+#endif
+
// get heap status, analog input value and all GPIO statuses in one json call
/*webServer.on(F("/all"), HTTP_GET, []() {
String json;
@@ -1851,17 +1583,24 @@ void httpSetup()
#endif
#if HASP_USE_WIFI > 0
webServer.on(F("/config/wifi"), webHandleWifiConfig);
+#endif
+#if HASP_USE_GPIO > 0
+ webServer.on(F("/config/gpio"), webHandleGpioConfig);
#endif
webServer.on(F("/screenshot"), webHandleScreenshot);
webServer.on(F("/saveConfig"), webHandleSaveConfig);
webServer.on(F("/resetConfig"), httpHandleResetConfig);
webServer.on(F("/firmware"), webHandleFirmware);
+#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
webServer.on(
F("/update"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, webHandleFirmwareUpdate);
webServer.on(F("/espfirmware"), httpHandleEspFirmware);
+#endif
webServer.on(F("/reboot"), httpHandleReboot);
webServer.onNotFound(httpHandleNotFound);
+#if HASP_USE_WIFI > 0
}
+#endif
// Shared pages
webServer.on(F("/about"), webHandleAbout);
@@ -1879,7 +1618,11 @@ void httpReconnect()
if(webServerStarted) {
webStop();
- } else if(WiFi.status() == WL_CONNECTED || WiFi.getMode() != WIFI_STA) {
+ } else
+#if HASP_USE_WIFI > 0
+ if(WiFi.status() == WL_CONNECTED || WiFi.getMode() != WIFI_STA)
+#endif
+ {
webStart();
}
}
@@ -1944,5 +1687,24 @@ bool httpSetConfig(const JsonObject & settings)
return changed;
}
-#endif
+size_t httpClientWrite(const uint8_t * buf, size_t size)
+{
+ /***** Sending 16Kb at once freezes on STM32 EthernetClient *****/
+ size_t bytes_sent = 0;
+ while(bytes_sent < size) {
+ if(!webServer.client()) return bytes_sent;
+ if(size - bytes_sent >= 2048) {
+ bytes_sent += webServer.client().write(buf + bytes_sent, 2048);
+ } else {
+ bytes_sent += webServer.client().write(buf + bytes_sent, size - bytes_sent);
+ }
+ // Serial.println(bytes_sent);
+
+ // stm32_eth_scheduler(); // already in write
+ // webServer.client().flush();
+ delay(1); // Fixes the freeze
+ }
+ return bytes_sent;
+}
+
#endif
\ No newline at end of file
diff --git a/src/hasp_http.h b/src/hasp_http.h
index d7a17db5..3caf1b7f 100644
--- a/src/hasp_http.h
+++ b/src/hasp_http.h
@@ -9,6 +9,8 @@ void httpLoop(void);
void httpEvery5Seconds(void);
void httpReconnect(void);
+size_t httpClientWrite(const uint8_t *buf, size_t size); // Screenshot Write Data
+
bool httpGetConfig(const JsonObject & settings);
bool httpSetConfig(const JsonObject & settings);
diff --git a/src/hasp_mdns.cpp b/src/hasp_mdns.cpp
index 7beb2941..c6613820 100644
--- a/src/hasp_mdns.cpp
+++ b/src/hasp_mdns.cpp
@@ -13,10 +13,10 @@
#include "hasp_config.h"
#include "hasp_conf.h"
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT>0
#include "hasp_mqtt.h"
#endif
-#if HASP_USE_MDNS
+#if HASP_USE_MDNS>0
#include "hasp_mdns.h"
#endif
diff --git a/src/hasp_mqtt.cpp b/src/hasp_mqtt.cpp
index eef09b2d..4bb7ef38 100644
--- a/src/hasp_mqtt.cpp
+++ b/src/hasp_mqtt.cpp
@@ -1,5 +1,5 @@
#include "hasp_conf.h"
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT>0
#include
#include "ArduinoJson.h"
@@ -11,10 +11,22 @@
#if defined(ARDUINO_ARCH_ESP32)
#include
-#else
+WiFiClient mqttNetworkClient;
+#elif defined(ARDUINO_ARCH_ESP8266)
#include
#include
#include
+WiFiClient mqttNetworkClient;
+#else
+
+#if defined(W5500_MOSI) && defined(W5500_MISO) && defined(W5500_SCLK)
+#define W5500_LAN
+#include
+#else
+#include
+#endif
+
+EthernetClient mqttNetworkClient;
#endif
#include "hasp_hal.h"
@@ -97,8 +109,7 @@ const String mqttLightSubscription = "hasp/" + String(haspGetNodename())
const String mqttLightBrightSubscription = "hasp/" + String(haspGetNodename()) + "/brightness/#";
*/
-WiFiClient mqttWifiClient;
-PubSubClient mqttClient(mqttWifiClient);
+PubSubClient mqttClient(mqttNetworkClient);
////////////////////////////////////////////////////////////////////////////////////////////////////
// Send changed values OUT
@@ -179,11 +190,13 @@ void mqtt_send_statusupdate()
snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"),
haspGetVersion().c_str(), long(millis() / 1000));
strcat(buffer, data);
+#if HASP_USE_WIFI>0
snprintf_P(buffer, sizeof(buffer), PSTR("\"ssid\":\"%s\",\"rssi\":%i,\"ip\":\"%s\","), WiFi.SSID().c_str(),
WiFi.RSSI(), WiFi.localIP().toString().c_str());
strcat(data, buffer);
+#endif
snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"espCore\":\"%s\","),
- ESP.getFreeHeap(), halGetHeapFragmentation(), halGetCoreVersion().c_str());
+ halGetFreeHeap(), halGetHeapFragmentation(), halGetCoreVersion().c_str());
strcat(data, buffer);
snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"),
haspGetPage(), (HASP_NUM_PAGES));
@@ -339,9 +352,11 @@ void mqttReconnect()
bool mqttFirstConnect = true;
{
- byte mac[6];
- WiFi.macAddress(mac);
- snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%2x%2x%2x"), mqttNodeName, mac[3], mac[4], mac[5]);
+ String mac = halGetMacAddress(3, "");
+ mac.toLowerCase();
+ memset(mqttClientId, 0 ,sizeof(mqttClientId));
+ snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("plate_%s"), mac.c_str());
+ Log.verbose(mqttClientId);
}
// Attempt to connect and set LWT and Clean Session
@@ -537,7 +552,7 @@ bool mqttSetConfig(const JsonObject & settings)
}
// Prefill node name
if(strlen(mqttNodeName) == 0) {
- String mac = wifiGetMacAddress(3, "");
+ String mac = halGetMacAddress(3, "");
mac.toLowerCase();
snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR("plate_%s"), mac.c_str());
changed = true;
diff --git a/src/hasp_oobe.cpp b/src/hasp_oobe.cpp
index 7f91127e..e63d27fe 100644
--- a/src/hasp_oobe.cpp
+++ b/src/hasp_oobe.cpp
@@ -14,7 +14,7 @@
#include "hasp_config.h"
#include "hasp_dispatch.h"
-#if HASP_USE_QRCODE != 0
+#if HASP_USE_QRCODE > 0
#include "lv_qrcode.h"
#endif
@@ -128,7 +128,7 @@ static void oobeSetupQR(const char * ssid, const char * pass)
lv_obj_set_style_local_bg_opa(container, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0);
lv_obj_set_style_local_border_opa(container, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0);
-#if HASP_USE_QRCODE != 0
+#if HASP_USE_QRCODE > 0
snprintf_P(buffer, sizeof(buffer), PSTR("WIFI:S:%s;T:WPA;P:%s;;"), ssid, pass);
lv_obj_t * qr = lv_qrcode_create(oobepage[0], 120, LV_COLOR_BLACK, LV_COLOR_WHITE);
diff --git a/src/hasp_ota.cpp b/src/hasp_ota.cpp
index 188fbcc0..cc7a3fca 100644
--- a/src/hasp_ota.cpp
+++ b/src/hasp_ota.cpp
@@ -10,11 +10,11 @@
#include "hasp_conf.h"
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT>0
#include "hasp_mqtt.h"
#endif
-#if HASP_USE_MDNS
+#if HASP_USE_MDNS>0
#include "hasp_mdns.h"
#endif
diff --git a/src/hasp_slave.cpp b/src/hasp_slave.cpp
new file mode 100644
index 00000000..7ae71a3c
--- /dev/null
+++ b/src/hasp_slave.cpp
@@ -0,0 +1,165 @@
+/*********************
+ * INCLUDES
+ *********************/
+#if HASP_USE_TASMOTA_SLAVE>0
+
+#include "hasp_slave.h"
+#include
+#include "ArduinoJson.h"
+#include "ArduinoLog.h"
+#include "hasp_dispatch.h"
+#include "hasp_gui.h"
+#include "hasp_hal.h"
+#include "hasp_tft.h"
+#include "hasp_config.h"
+#include "hasp.h"
+#include "tasmotaSlave.h"
+
+// set RX and TX pins
+HardwareSerial Serial2(PD6, PD5);
+TasmotaSlave slave(&Serial2);
+
+#define slaveNodeTopic "hasp/"
+
+unsigned long updateLedTimer = 0; // timer in msec for tele mqtt send
+unsigned long updatLedPeriod = 1000; // timer in msec for tele mqtt send
+
+bool ledstate = false;
+
+
+void IRAM_ATTR slave_send_state(const __FlashStringHelper * subtopic, const char * payload)
+{
+ // page = 0
+ // p[0].b[0].attr = abc
+ // dim = 100
+ // idle = 0/1
+ // light = 0/1
+ // brightness = 100
+
+ char cBuffer[strlen(payload) + 64];
+ memset(cBuffer, 0 ,sizeof(cBuffer));
+ snprintf(cBuffer, sizeof(cBuffer), PSTR("publish %sstate/%s %s"), slaveNodeTopic ,subtopic, payload);
+ slave.ExecuteCommand((char*)cBuffer);
+
+ // Log after char buffers are cleared
+ Log.notice(F("TAS PUB: %sstate/%S = %s"), slaveNodeTopic, subtopic, payload);
+}
+
+void IRAM_ATTR slave_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
+{
+ char cBuffer[192];
+ memset(cBuffer, 0 ,sizeof(cBuffer));
+ snprintf_P(cBuffer, sizeof(cBuffer), PSTR("publish %sstate/json {\"p[%u].b[%u].%s\":\"%s\"}"), slaveNodeTopic, pageid, btnid, attribute, data);
+ slave.ExecuteCommand((char*)cBuffer);
+ // Log after char buffers are cleared
+ Log.notice(F("TAS PUB: %sstate/json = {\"p[%u].b[%u].%s\":\"%s\"}"), slaveNodeTopic, pageid, btnid, attribute, data);
+}
+
+void slave_send_input(uint8_t id, const char * payload)
+{
+ // Log.trace(F("MQTT TST: %sstate/input%u = %s"), mqttNodeTopic, id, payload); // to be removed
+
+ char cBuffer[strlen(payload) + 64];
+ memset(cBuffer, 0 ,sizeof(cBuffer));
+ snprintf_P(cBuffer, sizeof(cBuffer), PSTR("publish %sstate/input%u %s"), slaveNodeTopic, id, payload);
+ slave.ExecuteCommand((char*)cBuffer);
+
+ // Log after char buffers are cleared
+ Log.notice(F("TAS PUB: %sstate/input%u = %s"), slaveNodeTopic, id, payload);
+}
+
+void TASMO_TELE_JSON()
+{ // Periodically publish a JSON string indicating system status
+ char data[3 * 128];
+ {
+ char buffer[128];
+ snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"),
+ haspGetVersion().c_str(), long(millis() / 1000));
+ strcat(buffer, data);
+ snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"),
+ haspGetPage(), (HASP_NUM_PAGES));
+ strcat(data, buffer);
+ snprintf_P(buffer, sizeof(buffer), PSTR("\"tftDriver\":\"%s\",\"tftWidth\":%u,\"tftHeight\":%u}"),
+ tftDriverName().c_str(), (TFT_WIDTH), (TFT_HEIGHT));
+ strcat(data, buffer);
+ }
+ slave.sendJSON((char*)data);
+ // slave_send_state(F("statusupdate"), data);
+ // debugLastMillis = millis();
+}
+
+void TASMO_DATA_RECEIVE(char *data)
+{
+ Log.verbose(F("TAS: Slave IN [%s]"), data);
+
+ char dataType[3];
+ memset(dataType, 0 ,sizeof(dataType));
+ snprintf_P(dataType, sizeof(dataType), data);
+ Log.verbose(F("TAS: dataType [%s]"), dataType);
+
+ if (!strcmp(dataType, "p[")){ //
+ dispatchCommand(data);
+ } else if (!strcmp(dataType, "[\"")) {
+ dispatchJson(data);
+ } else {
+ char slvCmd[20],slvVal[60];
+ memset(slvCmd, 0 ,sizeof(slvCmd));
+ memset(slvVal, 0 ,sizeof(slvVal));
+ sscanf(data,"%[^=] =%s", slvCmd, slvVal);
+
+ Log.verbose(F("TAS: Cmd[%s] Val[%s]"), slvCmd, slvVal);
+
+ if (!strcmp(slvCmd, "calData")){
+ if (strlen(slvVal) != 0) {
+ char cBuffer[strlen(slvVal) + 24];
+ memset(cBuffer, 0 ,sizeof(cBuffer));
+ snprintf_P(cBuffer, sizeof(cBuffer), PSTR("{'calibration':[%s]}"), slvVal);
+ dispatchConfig("gui",cBuffer);
+ } else {
+ dispatchConfig("gui","");
+ }
+ } else if (!strcmp(slvCmd, "jsonl")) {
+ dispatchJsonl(slvVal);
+ } else if (!strcmp(slvCmd, "clearpage")) {
+ dispatchClearPage(slvVal);
+ } else {
+ dispatchCommand(data);
+ }
+ }
+}
+
+void TASMO_EVERY_SECOND(void)
+{
+ if (ledstate) {
+ ledstate = false;
+ //digitalWrite(HASP_OUTPUT_PIN, 1);
+ // Log.verbose(F("LED OFF"));
+ } else {
+ ledstate = true;
+ //digitalWrite(HASP_OUTPUT_PIN, 0);
+ // Log.verbose(F("LED ON"));
+ }
+}
+
+void slaveSetup()
+{
+ Serial2.begin(HASP_SLAVE_SPEED);
+ // slave.attach_FUNC_EVERY_SECOND(TASMO_EVERY_SECOND);
+ slave.attach_FUNC_JSON(TASMO_TELE_JSON);
+ slave.attach_FUNC_COMMAND_SEND(TASMO_DATA_RECEIVE);
+
+ Log.notice(F("TAS: HASP SLAVE LOADED"));
+}
+
+void slaveLoop(void)
+{
+ slave.loop();
+ // demo code to run the led without tasmota
+ // if ((millis() - updateLedTimer) >= updatLedPeriod) {
+ // updateLedTimer = millis();
+ // TASMO_EVERY_SECOND();
+ // }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/hasp_slave.h b/src/hasp_slave.h
new file mode 100644
index 00000000..772a471c
--- /dev/null
+++ b/src/hasp_slave.h
@@ -0,0 +1,20 @@
+#ifndef HASP_SLAVE_H
+#define HASP_SLAVE_H
+
+#include "ArduinoJson.h"
+
+#define HASP_SLAVE_SPEED 57600
+
+void TASMO_EVERY_SECOND(void);
+void TASMO_DATA_RECEIVE(char *data);
+void IRAM_ATTR slave_send_state(const __FlashStringHelper * subtopic, const char * payload);
+void IRAM_ATTR slave_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data);
+void slave_send_input(uint8_t id, const char * payload);
+void slave_send_statusupdate();
+
+
+void slaveSetup();
+void slaveLoop(void);
+
+
+#endif
\ No newline at end of file
diff --git a/src/hasp_spiffs.cpp b/src/hasp_spiffs.cpp
index fdd64f8a..b916b07a 100644
--- a/src/hasp_spiffs.cpp
+++ b/src/hasp_spiffs.cpp
@@ -5,7 +5,7 @@
#include "hasp_conf.h"
#include "hasp_spiffs.h"
-#if HASP_USE_SPIFFS
+#if HASP_USE_SPIFFS>0
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
@@ -14,7 +14,7 @@
void spiffsInfo()
{ // Get all information of your SPIFFS
-#if defined(ARDUINO_ARCH_ESP8266)
+#if 0
FSInfo fs_info;
SPIFFS.info(fs_info);
@@ -91,7 +91,7 @@ void spiffsSetup()
{
// no SPIFFS settings, as settings depend on SPIFFS
-#if HASP_USE_SPIFFS
+#if HASP_USE_SPIFFS>0
#if defined(ARDUINO_ARCH_ESP8266)
if(!SPIFFS.begin()) {
#else
@@ -102,25 +102,4 @@ void spiffsSetup()
Log.verbose(F("FILE: SPI Flash FS mounted"));
}
#endif
-}
-
-String spiffsFormatBytes(size_t bytes)
-{
- String output((char *)0);
- output.reserve(128);
-
- if(bytes < 1024) {
- output += bytes;
- } else if(bytes < (1024 * 1024)) {
- output += bytes / 1024.0;
- output += "K";
- } else if(bytes < (1024 * 1024 * 1024)) {
- output += bytes / 1024.0 / 1024.0;
- output += "M";
- } else {
- output += bytes / 1024.0 / 1024.0 / 1024.0;
- output += "G";
- }
- output += "B";
- return output;
}
\ No newline at end of file
diff --git a/src/hasp_spiffs.h b/src/hasp_spiffs.h
index 39dbb956..c0dadaca 100644
--- a/src/hasp_spiffs.h
+++ b/src/hasp_spiffs.h
@@ -7,6 +7,5 @@ void spiffsSetup(void);
void spiffsList();
void spiffsInfo();
-String spiffsFormatBytes(size_t bytes);
#endif
\ No newline at end of file
diff --git a/src/hasp_telnet.cpp b/src/hasp_telnet.cpp
index b59c2096..e6595dba 100644
--- a/src/hasp_telnet.cpp
+++ b/src/hasp_telnet.cpp
@@ -9,11 +9,20 @@
#include "hasp_config.h"
#include "hasp_dispatch.h"
#include "hasp_telnet.h"
+#include "hasp_conf.h"
#if defined(ARDUINO_ARCH_ESP32)
#include
-#else
+WiFiClient telnetClient;
+static WiFiServer * telnetServer;
+#elif defined(ARDUINO_ARCH_ESP8266)
#include
+WiFiClient telnetClient;
+static WiFiServer * telnetServer;
+#else
+//#include
+EthernetClient telnetClient;
+static EthernetServer telnetServer(23);
#endif
#define TELNET_UNAUTHENTICATED 0
@@ -21,12 +30,14 @@
#define TELNET_USERNAME_NOK 99
#define TELNET_AUTHENTICATED 255
+#if HASP_USE_HTTP > 0
extern char httpUser[32];
extern char httpPassword[32];
+#endif
uint8_t telnetLoginState = TELNET_UNAUTHENTICATED;
-WiFiClient telnetClient;
-static WiFiServer * telnetServer;
+// WiFiClient telnetClient;
+// static WiFiServer * telnetServer;
uint16_t telnetPort = 23;
bool telnetInCommandMode = false;
uint8_t telnetEnabled = true; // Enable telnet debug output
@@ -36,7 +47,7 @@ char telnetInputBuffer[128];
void telnetClientDisconnect()
{
- Log.notice(F("Closing session from %s"), telnetClient.remoteIP().toString().c_str());
+ // Log.notice(F("Closing session from %s"), telnetClient.remoteIP().toString().c_str());
telnetClient.stop();
Log.unregisterOutput(1); // telnetClient
telnetLoginState = TELNET_UNAUTHENTICATED;
@@ -51,7 +62,7 @@ void telnetClientLogon()
telnetLoginState = TELNET_AUTHENTICATED; // User and Pass are correct
telnetLoginAttempt = 0; // Reset attempt counter
Log.registerOutput(1, &telnetClient, LOG_LEVEL_VERBOSE, true);
- Log.notice(F("Client login from %s"), telnetClient.remoteIP().toString().c_str());
+ // Log.notice(F("Client login from %s"), telnetClient.remoteIP().toString().c_str());
telnetClient.flush();
/* Echo locally as separate string */
// telnetClient.print(F("TELNET: Client login from "));
@@ -66,17 +77,25 @@ void telnetAcceptClient()
telnetClient.stop(); // client disconnected
Log.unregisterOutput(1); // telnetClient
}
- telnetClient = telnetServer->available(); // ready for new client
- Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str());
+ telnetClient = telnetServer.available(); // ready for new client
+ // Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str());
+ if(!telnetClient) {
+ Log.notice(F("Client NOT connected"));
+ return;
+ }
+ Log.notice(F("Client connected"));
/* Avoid a buffer here */
telnetClient.print(0xFF); // DO TERMINAL-TYPE
telnetClient.print(0xFD);
telnetClient.print(0x1B);
+#if HASP_USE_HTTP > 0
if(strlen(httpUser) != 0 || strlen(httpPassword) != 0) {
telnetClient.print(F("\r\nUsername: "));
telnetLoginState = TELNET_UNAUTHENTICATED;
- } else {
+ } else
+#endif
+ {
telnetClientLogon();
}
telnetInputIndex = 0; // reset input buffer index
@@ -100,6 +119,7 @@ static void telnetProcessLine()
switch(telnetLoginState) {
case TELNET_UNAUTHENTICATED: {
telnetClient.printf(PSTR("Password: %c%c%c"), 0xFF, 0xFB, 0x01); // Hide characters
+#if HASP_USE_HTTP > 0
telnetLoginState = strcmp(telnetInputBuffer, httpUser) == 0 ? TELNET_USERNAME_OK : TELNET_USERNAME_NOK;
break;
}
@@ -112,13 +132,16 @@ static void telnetProcessLine()
telnetLoginState = TELNET_UNAUTHENTICATED;
telnetLoginAttempt++; // Subsequent attempt
telnetClient.println(F("Authorization failed!\r\n"));
- Log.warning(F("Incorrect login attempt from %s"), telnetClient.remoteIP().toString().c_str());
+ // Log.warning(F("Incorrect login attempt from %s"), telnetClient.remoteIP().toString().c_str());
if(telnetLoginAttempt >= 3) {
telnetClientDisconnect();
} else {
telnetClient.print(F("Username: "));
}
}
+#else
+ telnetClientLogon();
+#endif
break;
}
default:
@@ -173,6 +196,15 @@ void telnetSetup()
// telnetSetConfig(settings);
if(telnetEnabled) { // Setup telnet server for remote debug output
+#if defined(STM32F4xx)
+ // if(!telnetServer) telnetServer = new EthernetServer(telnetPort);
+ // if(telnetServer) {
+ telnetServer.begin();
+ Log.notice(F("Debug telnet console started"));
+ // } else {
+ // Log.error(F("Failed to start telnet server"));
+ //}
+#else
if(!telnetServer) telnetServer = new WiFiServer(telnetPort);
if(telnetServer) {
telnetServer->setNoDelay(true);
@@ -189,12 +221,41 @@ void telnetSetup()
} else {
Log.error(F("Failed to start telnet server"));
}
+#endif
}
}
void IRAM_ATTR telnetLoop()
{ // Basic telnet client handling code from: https://gist.github.com/tablatronix/4793677ca748f5f584c95ec4a2b10303
+#if defined(STM32F4xx)
+Ethernet.schedule();
+ // if(telnetServer)
+ { // client is connected
+ EthernetClient client = telnetServer.available();
+ if(client) {
+ if(!telnetClient || !telnetClient.connected()) {
+ //telnetAcceptClient(client);
+
+ telnetClient = client; // ready for new client
+ // Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str());
+ if(!telnetClient) {
+ Log.notice(F("Client NOT connected"));
+ return;
+ }
+ Log.notice(F("Client connected"));
+
+ /* Avoid a buffer here */
+ // telnetClient.print(0xFF); // DO TERMINAL-TYPE
+ // telnetClient.print(0xFD);
+ // telnetClient.print(0x1B);
+
+ } else {
+ //client.stop(); // have client, block new connections
+ }
+ }
+ }
+#else
if(telnetServer && telnetServer->hasClient()) { // client is connected
if(!telnetClient || !telnetClient.connected()) {
telnetAcceptClient();
@@ -209,6 +270,7 @@ void IRAM_ATTR telnetLoop()
telnetProcessCharacter(telnetClient.read()); // client input processing
}
}
+#endif
}
bool telnetGetConfig(const JsonObject & settings)
diff --git a/src/hasp_tft.cpp b/src/hasp_tft.cpp
index b8f07ed0..031b5f23 100644
--- a/src/hasp_tft.cpp
+++ b/src/hasp_tft.cpp
@@ -3,6 +3,7 @@
#include "TFT_eSPI.h"
#include "hasp_tft.h"
+#include "hasp_hal.h"
#if defined(ARDUINO_ARCH_ESP8266)
ADC_MODE(ADC_VCC); // tftShowConfig measures the voltage on the pin
@@ -84,11 +85,10 @@ void tftShowConfig(TFT_eSPI & tft)
Log.verbose(F("TFT: TFT_eSPI : v%s"), tftSetup.version.c_str());
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32)
Log.verbose(F("TFT: Processor : ESP%x"), tftSetup.esp);
- Log.verbose(F("TFT: CPU freq. : %i MHz"), ESP.getCpuFreqMHz());
#else
Log.verbose(F("TFT: Processor : STM%x"), tftSetup.esp);
- Log.verbose(F("TFT: CPU freq. : %i MHz"), F_CPU/1000/1000);
#endif
+ Log.verbose(F("TFT: CPU freq. : %i MHz"), halGetCpuFreqMHz());
#if defined(ARDUINO_ARCH_ESP8266)
Log.verbose(F("TFT: Voltage : %2.2f V"), ESP.getVcc() / 918.0); // 918 empirically determined
@@ -98,6 +98,7 @@ void tftShowConfig(TFT_eSPI & tft)
#if defined(ARDUINO_ARCH_ESP8266)
Log.verbose(F("TFT: SPI overlap : %s"), (tftSetup.overlap == 1) ? PSTR("Yes") : PSTR("No"));
#endif
+
if(tftSetup.tft_driver != 0xE9D) // For ePaper displays the size is defined in the sketch
{
Log.verbose(F("TFT: Driver : %s"), tftDriverName().c_str()); // tftSetup.tft_driver);
@@ -155,14 +156,10 @@ void tftShowConfig(TFT_eSPI & tft)
tftPinInfo(F("TFT_D7"), tftSetup.pin_tft_d7);
if(tftSetup.serial == 1) {
- char buffer[8];
- snprintf_P(buffer, sizeof(buffer), "%4.2f", (float)tftSetup.tft_spi_freq / 10.0f);
- Log.verbose(F("TFT: Display SPI freq. : %s MHz"), buffer);
+ Log.verbose(F("TFT: Display SPI freq. : %d.%d MHz"), tftSetup.tft_spi_freq / 10, tftSetup.tft_spi_freq % 10);
}
if(tftSetup.pin_tch_cs != -1) {
- char buffer[8];
- snprintf_P(buffer, sizeof(buffer), "%4.2f", (float)tftSetup.tch_spi_freq / 10.0f);
- Log.verbose(F("TFT: Touch SPI freq. : %s MHz"), buffer);
+ Log.verbose(F("TFT: Touch SPI freq. : %d.%d MHz"), tftSetup.tch_spi_freq / 10, tftSetup.tch_spi_freq % 10);
}
}
diff --git a/src/hasp_wifi.cpp b/src/hasp_wifi.cpp
index ecde60b0..2921b027 100644
--- a/src/hasp_wifi.cpp
+++ b/src/hasp_wifi.cpp
@@ -41,22 +41,6 @@ uint8_t wifiReconnectCounter = 0;
// const byte DNS_PORT = 53;
// DNSServer dnsServer;
-String wifiGetMacAddress(int start, const char * seperator)
-{
- byte mac[6];
- WiFi.macAddress(mac);
- String cMac((char *)0);
- cMac.reserve(32);
-
- for(int i = start; i < 6; ++i) {
- if(mac[i] < 0x10) cMac += "0";
- cMac += String(mac[i], HEX);
- if(i < 5) cMac += seperator;
- }
- cMac.toUpperCase();
- return cMac;
-}
-
void wifiConnected(IPAddress ipaddress)
{
Log.notice(F("WIFI: Received IP address %s"), ipaddress.toString().c_str());
diff --git a/src/hasp_wifi.h b/src/hasp_wifi.h
index 3ee27d27..ea7b397c 100644
--- a/src/hasp_wifi.h
+++ b/src/hasp_wifi.h
@@ -13,6 +13,4 @@ bool wifiTestConnection();
bool wifiGetConfig(const JsonObject & settings);
bool wifiSetConfig(const JsonObject & settings);
-String wifiGetMacAddress(int start, const char * seperator);
-
#endif
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 5bb44c72..e03e3c21 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,12 +1,11 @@
#include "hasp_conf.h" // load first
#include
+#include "hasp_conf.h"
#include "hasp_debug.h"
-#include "hasp_spiffs.h"
#include "hasp_config.h"
#include "hasp_gui.h"
#include "hasp.h"
-#include "hasp_conf.h"
#include "hasp_oobe.h"
#include "hasp_gpio.h"
@@ -22,15 +21,15 @@ void setup()
***************************/
/* Init Storage */
-#if HASP_USE_EEPROM
-// eepromSetup(); // Don't start at boot, only at write
+#if HASP_USE_EEPROM>0
+ eepromSetup(); // Don't start at boot, only at write
#endif
-#if HASP_USE_SPIFFS
+#if HASP_USE_SPIFFS>0
spiffsSetup();
#endif
-#if HASP_USE_SDCARD
+#if HASP_USE_SDCARD>0
sdcardSetup();
#endif
@@ -43,41 +42,45 @@ void setup()
* Apply User Configuration
***************************/
debugSetup();
- gpioSetup();
- guiSetup();
-#if HASP_USE_WIFI
+#if HASP_USE_GPIO>0
+ gpioSetup();
+#endif
+
+#if HASP_USE_WIFI>0
wifiSetup();
#endif
+
+ guiSetup();
oobeSetup();
haspSetup();
-#if HASP_USE_WIFI
-
-#if HASP_USE_HTTP
- httpSetup();
-#endif
-
-#if HASP_USE_MQTT
- mqttSetup();
-#endif
-
-#if HASP_USE_TELNET
- telnetSetup();
-#endif
-
-#if HASP_USE_MDNS
+#if HASP_USE_MDNS>0
mdnsSetup();
#endif
-#if HASP_USE_OTA
+#if HASP_USE_OTA>0
otaSetup();
#endif
-#endif // WIFI
+#if HASP_USE_ETHERNET > 0
+ ethernetSetup();
+#endif
-#if HASP_USE_BUTTON
- buttonSetup();
+#if HASP_USE_MQTT>0
+ mqttSetup();
+#endif
+
+#if HASP_USE_HTTP>0
+ httpSetup();
+#endif
+
+#if HASP_USE_TELNET > 0
+ telnetSetup();
+#endif
+
+#if HASP_USE_TASMOTA_SLAVE>0
+ slaveSetup();
#endif
mainLastLoopTime = millis() - 1000; // reset loop counter
@@ -86,82 +89,98 @@ void setup()
void loop()
{
/* Storage Loops */
-#if HASP_USE_EEPROM
- eepromLoop();
-#endif
- // spiffsLoop();
-#if HASP_USE_SDCARD
- // sdcardLoop();
-#endif
+ /*
+ #if HASP_USE_EEPROM>0
+ // eepromLoop(); // Not used
+ #endif
- // configLoop();
+ #if HASP_USE_SPIFFS>0
+ // spiffsLoop(); // Not used
+ #endif
+
+ #if HASP_USE_SDCARD>0
+ // sdcardLoop(); // Not used
+ #endif
+
+ // configLoop(); // Not used
+ */
/* Graphics Loops */
// tftLoop();
guiLoop();
-
/* Application Loops */
// haspLoop();
+ debugLoop();
+
+#if HASP_USE_GPIO>0
+ gpioLoop();
+#endif
/* Network Services Loops */
-#if HASP_USE_WIFI
+#if HASP_USE_ETHERNET > 0
+ ethernetLoop();
+#endif
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT>0
mqttLoop();
#endif // MQTT
-#if HASP_USE_HTTP
+#if HASP_USE_HTTP>0
httpLoop();
#endif // HTTP
-#if HASP_USE_TELNET
- telnetLoop();
-#endif // TELNET
-
-#if HASP_USE_MDNS
+#if HASP_USE_MDNS>0
mdnsLoop();
#endif // MDNS
-#if HASP_USE_BUTTON
- buttonLoop();
-#endif // BUTTON
-
-#if HASP_USE_OTA
+#if HASP_USE_OTA>0
otaLoop();
#endif // OTA
-#endif // WIFI
+#if HASP_USE_TELNET > 0
+ telnetLoop();
+#endif // TELNET
- // Every Second Loop
+#if HASP_USE_TASMOTA_SLAVE>0
+ slaveLoop();
+#endif // TASMOTASLAVE
+
+ // digitalWrite(HASP_OUTPUT_PIN, digitalRead(HASP_INPUT_PIN)); // sets the LED to the button's value
+
+ /* Timer Loop */
if(millis() - mainLastLoopTime >= 1000) {
/* Run Every Second */
-#if HASP_USE_OTA
+#if HASP_USE_OTA>0
otaEverySecond();
#endif
debugEverySecond();
/* Run Every 5 Seconds */
- if(mainLoopCounter == 0 || mainLoopCounter == 4) {
-#if HASP_USE_HTTP
+ if(mainLoopCounter == 0 || mainLoopCounter == 5) {
+#if HASP_USE_WIFI > 0
+ isConnected = wifiEvery5Seconds();
+#endif
+
+#if HASP_USE_ETHERNET > 0
+ isConnected = ethernetEvery5Seconds();
+#endif
+
+#if HASP_USE_HTTP > 0
httpEvery5Seconds();
#endif
-#if HASP_USE_WIFI
- isConnected = wifiEvery5Seconds();
-
-#if HASP_USE_MQTT
+#if HASP_USE_MQTT > 0
mqttEvery5Seconds(isConnected);
-#endif
-
#endif
}
- /* Update counters */
+ /* Reset loop counter every 10 seconds */
+ if(mainLoopCounter >= 9) {
+ mainLoopCounter = 0;
+ } else {
+ mainLoopCounter++;
+ }
mainLastLoopTime += 1000;
- mainLoopCounter++;
- if(mainLoopCounter >= 10) {
- mainLoopCounter = 0;
- }
}
delay(3);
diff --git a/user_setups/esp32/d1-mini-esp32_ili9341.ini b/user_setups/esp32/d1-mini-esp32_ili9341.ini
new file mode 100644
index 00000000..bae61bc9
--- /dev/null
+++ b/user_setups/esp32/d1-mini-esp32_ili9341.ini
@@ -0,0 +1,23 @@
+;***************************************************;
+; D1 Mini ESP32 with Lolin TFT 2.4" ;
+; - D1-mini-esp32 board ;
+; - ili9341 TFT ;
+; - xpt2606 touch controller ;
+;***************************************************;
+
+[env:d1mini32-lolintft24]
+platform = espressif32@^1.12.0
+board = wemos_d1_mini32
+upload_port = COM5 ; To change the port, use platform_override.ini
+monitor_port = COM5 ; To change the port, use platform_override.ini
+board_build.partitions = default.csv
+build_flags =
+ ${flags.esp32_flags}
+; -- TFT_eSPI build options ------------------------
+ ${lcd.lolin24}
+ ${pins.vspi32}
+ -D TFT_DC=5
+ -D TFT_CS=26
+ -D TFT_RST=-1 ; RST
+ -D TFT_BCKL=-1 ; None, configurable via web UI (e.g. 21)
+ -D TOUCH_CS=17 ; (can also be 22 or 16)
diff --git a/user_setups/esp32/d132-unoshield_ili9486_parallel.ini b/user_setups/esp32/d132-unoshield_ili9486_parallel.ini
new file mode 100644
index 00000000..e3c45355
--- /dev/null
+++ b/user_setups/esp32/d132-unoshield_ili9486_parallel.ini
@@ -0,0 +1,49 @@
+;***************************************************;
+; ESP32 build with ;
+; - Wemos "TTGo" D1 R32 board ;
+; - ili9486 TFT ;
+;***************************************************;
+
+[env:d132-unoshield]
+platform = espressif32
+board = esp32dev
+upload_port = COM4 ; To change the port, use platform_override.ini
+monitor_port = COM4 ; To change the port, use platform_override.ini
+
+build_flags =
+ ${flags.esp32_flags}
+; -- TFT_eSPI build options ------------------------
+ -D USER_SETUP_LOADED=1
+ ;-D ST7796_DRIVER=1 ;3.95inch Arduino Display-UNO
+ -D ILI9486_DRIVER=1 ;3.5inch Arduino Display-UNO
+ -D ESP32_PARALLEL=1
+ -D TFT_ROTATION=${lcd.TFT_ROTATION}
+ -D TFT_WIDTH=320
+ -D TFT_HEIGHT=480
+ ${pins.vspi32}
+ -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
+ -D TFT_CS=33 ; Chip select control pin
+ -D TFT_DC=15 ; Data Command control pin - must use a pin in the range 0-31
+ -D TFT_RST=32 ; Reset pin
+ -D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
+ -D TFT_RD=2
+ -D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
+ -D TFT_D1=13 ; so a single register write sets/clears all bits
+ -D TFT_D2=26
+ -D TFT_D3=25
+ -D TFT_D4=17
+ -D TFT_D5=16
+ -D TFT_D6=27
+ -D TFT_D7=14
+ -D SD_CS=5
+ -D SPI_FREQUENCY=40000000
+ ;-D SPI_TOUCH_FREQUENCY=2500000 ; Uses ADC instead
+ -D SPI_READ_FREQUENCY=20000000
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
+
+; -- Library options -------------------------------
+lib_deps =
+ ${env.lib_deps}
+
+src_filter = +<*> +<../drivers/stm32f429_disco>
diff --git a/user_setups/esp32/esp32-dev_ili9488.ini b/user_setups/esp32/esp32-dev_ili9488.ini
new file mode 100644
index 00000000..b3fac875
--- /dev/null
+++ b/user_setups/esp32/esp32-dev_ili9488.ini
@@ -0,0 +1,48 @@
+;***************************************************;
+; Generic ESP32 build with ;
+; - ili9488 TFT SPI 4-WIRE ;
+; - xpt2606 touch controller ;
+;***************************************************;
+
+[env:esp32dev-ili9488]
+platform = espressif32
+board = esp32dev
+upload_port = COM2 ; To change the port, use platform_override.ini
+monitor_port = COM2 ; To change the port, use platform_override.ini
+; upload_protocol = espota ; Use ArduinoOTA after flashing over serial
+; upload_port = 10.4.0.171 ; IP of the ESP
+; upload_flags =
+; --port=3232
+debug_tool = esp-prog
+debug_init_break = tbreak setup
+
+build_flags =
+ ${flags.esp32_flags}
+; -- TFT_eSPI build options ------------------------
+ -D USER_SETUP_LOADED=1
+ -D ILI9488_DRIVER=1
+ -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
+ -D TFT_WIDTH=320
+ -D TFT_HEIGHT=480
+ -D TFT_MISO=19 ;// (leave TFT SDO disconnected if other SPI devices share MISO)
+ -D TFT_MOSI=23
+ -D TFT_SCLK=18
+ -D TFT_CS=15 ;// Chip select control pin
+ -D TFT_DC=2 ;// Data Command control pin
+ -D TFT_RST=4 ;// Reset pin (could connect to RST pin)
+ -D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
+ -D SUPPORT_TRANSACTIONS
+ -D TOUCH_CS=22
+ -D TOUCH_DRIVER=0 ; XPT2606 Resistive touch panel driver
+ -D SPI_FREQUENCY=27000000
+ -D SPI_TOUCH_FREQUENCY=2500000
+ -D SPI_READ_FREQUENCY=16000000
+
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
+
+; -- Library options -------------------------------
+lib_deps =
+ ${env.lib_deps}
+
+src_filter = +<*> +<../drivers/stm32f429_disco>
diff --git a/user_setups/esp32/esp32-dev_ili9488_parallel.ini b/user_setups/esp32/esp32-dev_ili9488_parallel.ini
new file mode 100644
index 00000000..52e79ade
--- /dev/null
+++ b/user_setups/esp32/esp32-dev_ili9488_parallel.ini
@@ -0,0 +1,46 @@
+;***************************************************;
+; Generic ESP32 build with ;
+; - ESP32dev board ;
+; - ili9488 TFT ;
+; - GT911 touch controller ;
+;***************************************************;
+
+[env:esp32dev-mrb3511]
+platform = espressif32
+board = esp32dev
+upload_port = COM1 ; To change the port, use platform_override.ini
+monitor_port = COM1 ; To change the port, use platform_override.ini
+debug_tool = esp-prog
+debug_init_break = tbreak setup
+
+build_flags =
+ ${flags.esp32_flags}
+; -- TFT_eSPI build options ------------------------
+ ${lcd.mrb3511}
+ -D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
+ -D TFT_CS=33 ; Chip select control pin
+ -D TFT_DC=15 ; =RS; Data Command control pin - must use a pin in the range 0-31
+ -D TFT_RST=32 ; Reset pin
+ -D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
+ -D TFT_RD=2
+ -D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
+ -D TFT_D1=13 ; so a single register write sets/clears all bits
+ -D TFT_D2=26
+ -D TFT_D3=25
+ -D TFT_D4=17
+ -D TFT_D5=16
+ -D TFT_D6=27
+ -D TFT_D7=14
+ -D TOUCH_SDA=21
+ -D TOUCH_SCL=22
+ -D TOUCH_IRQ=34 ; use 34-39 as these are input only pins
+ -D TOUCH_RST=-1 ; not used, connected to 3.3V
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
+
+; -- Library options -------------------------------
+lib_deps =
+ ${env.lib_deps}
+ https://github.com/netwizeBE/arduino-goodix.git ; GT911 touch screen driver
+
+src_filter = +<*> +<../drivers/stm32f429_disco>
diff --git a/user_setups/esp32/esp32cam_st7796.ini b/user_setups/esp32/esp32cam_st7796.ini
new file mode 100644
index 00000000..cc111771
--- /dev/null
+++ b/user_setups/esp32/esp32cam_st7796.ini
@@ -0,0 +1,41 @@
+;***************************************************;
+; ESP32 build with ;
+; - ESP32Cam board ;
+; - st7796 TFT ;
+; - xpt2606 touch controller ;
+;***************************************************;
+
+[env:esp32cam-st7796]
+platform = espressif32
+board = esp32cam
+; upload_port = COM18 ; To change the port, use platform_override.ini
+; monitor_port = COM18 ; To change the port, use platform_override.ini
+; upload_protocol = espota ; Use ArduinoOTA after flashing over serial
+; upload_port = x.x.x.x; IP of the ESP
+; upload_flags =
+; --port=3232
+
+debug_tool = esp-prog
+debug_init_break = tbreak setup
+;board_build.partitions = min_spiffs.csv
+board_build.partitions = default.csv
+;ESP32 CAM PINS
+build_flags =
+ ${flags.esp32_flags}
+; -- TFT_eSPI build options ------------------------
+ ${lcd.raspberrypi}
+ -D USE_HSPI_PORT
+ ${pins.hspi32}
+ -D TFT_CS=15
+ -D TFT_DC=2
+ -D TFT_RST=-1 ; 3.3v
+ -D TOUCH_CS=0 ; 3 ; RX
+ -D TFT_BCKL=-1
+
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
+
+; -- Library options -------------------------------
+lib_deps =
+ ${env.lib_deps}
+
diff --git a/user_setups/esp32/nodemcu-32s_st7796.ini b/user_setups/esp32/nodemcu-32s_st7796.ini
new file mode 100644
index 00000000..9ccd8f96
--- /dev/null
+++ b/user_setups/esp32/nodemcu-32s_st7796.ini
@@ -0,0 +1,31 @@
+;***************************************************;
+; NodeMCU32S with build with ;
+; - st7796 TFT ;
+; - MHS-4" RPI Display-B ;
+; - xpt2606 touch controller ;
+;***************************************************;
+
+[env:nodemcu32s-raspi]
+platform = espressif32
+board = nodemcu-32s
+upload_port = COM3 ; To change the port, use platform_override.ini
+monitor_port = COM3 ; To change the port, use platform_override.ini
+debug_tool = esp-prog
+debug_init_break = tbreak setup
+
+build_flags =
+ ${flags.esp32_flags}
+; -- TFT_eSPI build options ------------------------
+ ${lcd.raspberrypi}
+ ${pins.vspi32}
+ -D TFT_CS=15
+ -D TFT_DC=4
+ -D TFT_RST=32
+ -D TOUCH_CS=22
+
+; -- Debugging options -----------------------------
+; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
+
+; -- Library options -------------------------------
+lib_deps =
+ ${env.lib_deps}
diff --git a/user_setups/esp8266/D1-mini_ili9341.ini b/user_setups/esp8266/D1-mini_ili9341.ini
new file mode 100644
index 00000000..bd669242
--- /dev/null
+++ b/user_setups/esp8266/D1-mini_ili9341.ini
@@ -0,0 +1,28 @@
+;***************************************************;
+; D1 Mini ESP8266 with Lolin TFT 2.4" ;
+; - D1-mini board ;
+; - ili9341 TFT ;
+; - xpt2606 touch controller ;
+;***************************************************;
+
+[env:d1mini-lolintft24]
+platform = espressif8266@^2.4.0 ;@2.3.2
+board = d1_mini
+upload_port = COM7 ; To change the port, use platform_override.ini
+monitor_port = COM7 ; To change the port, use platform_override.ini
+board_build.f_flash = 40000000L
+board_build.flash_mode = dout
+board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs
+board_build.f_cpu = 160000000L ; set frequency to 160MHz
+build_flags =
+ ${flags.esp8266_flags}
+; -- TFT_eSPI build options ------------------------
+ ${lcd.lolin24}
+ ;-D TFT_MISO=12 ;D6 Use default HSPI
+ ;-D TFT_MOSI=13 ;D7 Use default HSPI
+ ;-D TFT_SCLK=14 ;D5 Use default HSPI
+ -D TFT_DC=15 ;D8
+ -D TFT_CS=16 ;D0
+ -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
+ -D TOUCH_CS=0 ;D3 (can also be D1 or D2)
+ -D TFT_RST=-1 ;RST
diff --git a/user_setups/esp8266/esp8266_st7735.ini b/user_setups/esp8266/esp8266_st7735.ini
new file mode 100644
index 00000000..077eec02
--- /dev/null
+++ b/user_setups/esp8266/esp8266_st7735.ini
@@ -0,0 +1,38 @@
+;***************************************************;
+; ESP8266 build with ;
+; - ESP-12 board ;
+; - st7735 TFT ;
+;***************************************************;
+
+[env:esp12e-st7735]
+platform = espressif8266@^2.4.0 ;@2.3.2
+board = esp12e
+upload_port = COM8 ; To change the port, use platform_override.ini
+monitor_port = COM8 ; To change the port, use platform_override.ini
+board_build.f_flash = 40000000L
+board_build.flash_mode = dout
+board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs
+board_build.f_cpu = 160000000L ; set frequency to 160MHz
+build_flags =
+ ${flags.esp8266_flags}
+; -- TFT_eSPI build options ------------------------
+ -D USER_SETUP_LOADED=1
+ -D ST7735_DRIVER=1
+ -D ST7735_BLACKTAB=1
+ -D TFT_ROTATION=${lcd.TFT_ROTATION}
+ -D TFT_WIDTH=128
+ -D TFT_HEIGHT=160
+ -D TFT_MISO=-1 ;NC
+ -D TFT_MOSI=13 ;D7
+ -D TFT_SCLK=14 ;D5
+ -D TFT_CS=15 ;D8
+ -D TFT_DC=0 ;D3
+ -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
+ -D TOUCH_CS=-1 ;NC
+ -D TFT_RST=2 ;D4
+ -D SPI_FREQUENCY=27000000
+
+; -- Library options -------------------------------
+lib_deps =
+ ${env.lib_deps}
+ ;Ethernet@<2.0.0
diff --git a/user_setups/stm32f4xx/stm32f407-black_ili9341.ini b/user_setups/stm32f4xx/stm32f407-black_ili9341.ini
new file mode 100644
index 00000000..8f96fa44
--- /dev/null
+++ b/user_setups/stm32f4xx/stm32f407-black_ili9341.ini
@@ -0,0 +1,53 @@
+;***************************************************;
+; STM32F4 build with ;
+; - DIY_more board ;
+; - ili9341 TFT ;
+; - xpt2046 touch controller ;
+;***************************************************;
+
+[env:black_f407vg]
+platform = ststm32
+board = diymore_f407vgt
+board_build.mcu = stm32f407vgt6
+upload_protocol = dfu
+monitor_port = COM7 ; To change the port, use platform_override.ini
+build_flags =
+ ${env.build_flags}
+ ${flags.stm32_flags}
+ -I include/stm32f4
+; -- TFT_eSPI build options ------------------------
+ ${lcd.lolin24}
+ ;-D TFT_MISO=PB4 ;Default
+ ;-D TFT_MOSI=PB5 ;Default
+ ;-D TFT_SCLK=PB3 ;Default
+ -D TFT_CS=PE13 ;D8
+ -D TFT_DC=PE14 ;D3
+ -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
+ -D TOUCH_CS=PA6 ;NC
+ -D TFT_RST=-1 ;D4
+ -D HASP_OUTPUT_PIN=PE0 ; User LED D2 on DevEBox board
+ -D HASP_INPUT_PIN=PD15 ; User Button K1 on DevEBox board
+ -D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2
+ ;-D HAL_ETH_MODULE_ENABLED=1 ; enable ethernet support
+ ;-D LAN8742A_PHY_ADDRESS=0x01U ; set LAN8720 PHY address
+ -D HASP_USE_TASMOTA_SLAVE=1
+ -D HASP_USE_ETHERNET=1
+ -D W5500_MOSI=PB15 ;SPI2 MOSI
+ -D W5500_MISO=PB14 ;SPI2 MISO
+ -D W5500_SCLK=PB13 ;SPI2 SCLK
+ -D W5500_CS=PB6 ;SPI2 CS
+ -D W5500_RST=PD1 ;SPI2 CS
+
+lib_deps =
+ ${env.lib_deps}
+ Ticker@^3.1.5
+ ;Ethernet
+ ; STM32duino LwIP@^2.1.2
+ ; STM32duino STM32Ethernet@^1.0.5
+ https://github.com/stm32duino/LwIP.git
+ https://github.com/netwizeBE/Ethernet3.git
+ https://github.com/khoih-prog/EthernetWebServer_STM32
+
+src_filter = +<*> -<.git/> -<.svn/> - - - - - +
+
+;***************************************************
diff --git a/user_setups/stm32f4xx/stm32f407-devebox_ili9341.ini b/user_setups/stm32f4xx/stm32f407-devebox_ili9341.ini
new file mode 100644
index 00000000..43b5d65c
--- /dev/null
+++ b/user_setups/stm32f4xx/stm32f407-devebox_ili9341.ini
@@ -0,0 +1,52 @@
+;***************************************************;
+; STM32F4xx build with ;
+; - DevEBox board ;
+; - ili9341 TFT ;
+; - xpt2046 touch controller ;
+;***************************************************;
+
+[env:DevEBox_STM32F4xx]
+platform = ststm32
+board = black_f407zg
+board_build.mcu = stm32f407vgt6
+; upload_protocol = dfu
+upload_protocol = stlink
+debug_tool = stlink
+monitor_port = COM19 ; To change the port, use platform_override.ini
+build_flags =
+ ${env.build_flags}
+ ${flags.stm32_flags}
+ -I include/stm32f4
+; -- TFT_eSPI build options ------------------------
+ ${lcd.lolin24}
+ ;-D TFT_MISO=PB4 ;Default
+ ;-D TFT_MOSI=PB5 ;Default
+ ;-D TFT_SCLK=PB3 ;Default
+ -D TFT_CS=PE13 ;D8
+ -D TFT_DC=PE14 ;D3
+ -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
+ -D TOUCH_CS=PA6 ;NC
+ -D TFT_RST=-1 ;D4
+ -D STM32
+ -D TFT_SPI3
+ -D USE_DMA_TO_TFT
+ -D HASP_USE_TASMOTA_SLAVE=1
+ -D HASP_OUTPUT_PIN=PA1 ; User LED D2 on DevEBox board
+ -D HASP_INPUT_PIN=PA0 ; User Button K1 on DevEBox board
+ -D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2
+ -D HASP_USE_ETHERNET=1
+ -D USE_BUILTIN_ETHERNET=1
+ -D HAL_ETH_MODULE_ENABLED=1
+ ; -D LAN8742A_PHY_ADDRESS=0x01U ; moved to include\stm32f4\hal_conf_custom.h
+ ; -D DP83848_PHY_ADDRESS=0x01U
+
+lib_deps =
+ ${env.lib_deps}
+ Ticker@^3.1.5
+ ; STM32duino LwIP@^2.1.2
+ ; STM32duino STM32Ethernet@^1.0.5
+ https://github.com/stm32duino/LwIP.git
+ https://github.com/stm32duino/STM32Ethernet.git
+ https://github.com/khoih-prog/EthernetWebServer_STM32
+
+src_filter = +<*> -<.git/> -<.svn/> - - - - - +