Merge branch '0.2.0' into 0.1.0-fsmc

This commit is contained in:
fvanroie 2020-11-09 01:04:51 +01:00
commit 879a0288cc
48 changed files with 2596 additions and 1316 deletions

4
.gitignore vendored
View File

@ -10,6 +10,10 @@ src/user_config_override.h
platformio_override.ini
user_setups/active/*
## Test result files
*.html
*.xml
## Visual Studio Code specific ######
.vscode
.vscode/.browse.c_cpp.db*

View File

@ -4,6 +4,7 @@
[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/fvanroie/hasp-lvgl/blob/master/LICENSE)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
[![GitHub issues](https://img.shields.io/github/issues/fvanroie/hasp-lvgl.svg)](http://github.com/fvanroie/hasp-lvgl/issues)
[![Discord](https://img.shields.io/discord/538814618106331137?color=%237289DA&label=support&logo=discord&logoColor=white)][6]
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.
@ -61,8 +62,15 @@ git submodule update --init --recursive
Check out the [wiki](https://github.com/fvanroie/hasp-lvgl/wiki) for how-to's, information and frequently asked questions.
Support
---------------------------
For support using hasp-lvgl, please join the [#hasp-lvgl channel][6] on Discord.
[1]: https://github.com/aderusha/HASwitchPlate
[2]: https://github.com/littlevgl/lvgl
[3]: https://littlevgl.com/themes
[4]: https://github.com/fvanroie/HMI-Font-Pack/releases
[5]: https://fontawesome.com/cheatsheet/
[6]: https://discord.gg/VCWyuhF

View File

@ -1,6 +1,10 @@
#ifndef HASP_CONF_H
#define HASP_CONF_H
#define HASP_VERSION_MAJOR 0
#define HASP_VERSION_MINOR 2
#define HASP_VERSION_REVISION 1108
#define HASP_USE_APP 1
/* Network Services */
@ -31,7 +35,7 @@
#endif
#ifndef HASP_USE_SYSLOG
#define HASP_USE_SYSLOG 0
#define HASP_USE_SYSLOG 1
#endif
#ifndef HASP_USE_TELNET
@ -107,6 +111,21 @@
#endif
#if HASP_USE_ETHERNET > 0
#if defined(ARDUINO_ARCH_ESP32)
#include <ETH.h>
#define ETH_ADDR 0
#define ETH_POWER_PIN -1
#define ETH_MDC_PIN 23
#define ETH_MDIO_PIN 18
#define NRST 5
#define ETH_TYPE ETH_PHY_LAN8720
#define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT
#include "hasp_ethernet_esp32.h"
#warning Using ESP32 Ethernet LAN8720
#else
#if USE_BUILTIN_ETHERNET > 0
#include <LwIP.h>
#include <STM32Ethernet.h>
@ -121,6 +140,7 @@
#endif
#include "hasp_ethernet.h"
#endif
#endif
#if HASP_USE_MQTT > 0
#include "hasp_mqtt.h"
@ -144,6 +164,13 @@
#if HASP_USE_OTA > 0
#include "hasp_ota.h"
#ifndef HASP_OTA_PORT
#if defined(ARDUINO_ARCH_ESP32)
#define HASP_OTA_PORT 3232
#elif defined(ARDUINO_ARCH_ESP8266)
#define HASP_OTA_PORT 8266
#endif
#endif
#endif
#if HASP_USE_TASMOTA_SLAVE > 0

View File

@ -402,6 +402,7 @@ typedef void* lv_font_user_data_t;
#define LV_USE_THEME_EMPTY 1
#define LV_USE_THEME_TEMPLATE 1
#define LV_USE_THEME_HASP 1
/*=================
* Text settings

View File

@ -79,8 +79,8 @@ static inline bool openFont(File & file, const char * filename)
file = SPIFFS.open(filename, "r");
if(!file) {
// Log.error(F("FONT: %sOpening font: %s"), filename);
// return false;
Log.error(F("FONT: %sOpening font: %s"), filename);
return false;
}
return file;
}
@ -117,7 +117,7 @@ int lv_zifont_font_init(lv_font_t ** font, const char * font_path, uint16_t size
/* Initialize Last Glyph DSC */
dsc->last_glyph_dsc = (lv_zifont_char_t *)lv_mem_alloc(sizeof(lv_zifont_char_t));
_lv_memset(dsc->last_glyph_dsc, 0x00, sizeof(lv_zifont_char_t)); // lv_mem_alloc might be dirty
memset(dsc->last_glyph_dsc, 0x00, sizeof(lv_zifont_char_t)); // lv_mem_alloc might be dirty
if(dsc->last_glyph_dsc == NULL) return ZIFONT_ERROR_OUT_OF_MEMORY;
dsc->last_glyph_dsc->width = 0;
@ -156,8 +156,8 @@ int lv_zifont_font_init(lv_font_t ** font, const char * font_path, uint16_t size
if(!dsc->ascii_glyph_dsc) {
dsc->ascii_glyph_dsc = (lv_zifont_char_t *)lv_mem_alloc(sizeof(lv_zifont_char_t) * CHAR_CACHE_SIZE);
LV_ASSERT_MEM(dsc->ascii_glyph_dsc);
_lv_memset(dsc->ascii_glyph_dsc, 0x00,
sizeof(lv_zifont_char_t) * CHAR_CACHE_SIZE); // lv_mem_alloc might be dirty
memset(dsc->ascii_glyph_dsc, 0x00,
sizeof(lv_zifont_char_t) * CHAR_CACHE_SIZE); // lv_mem_alloc might be dirty
}
if(dsc->ascii_glyph_dsc == NULL) {
file.close();
@ -407,8 +407,10 @@ bool IRAM_ATTR lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t * font, lv_font_
uint32_t unicode_letter, uint32_t unicode_letter_next)
{
/* Only ascii characteres supported for now */
if(unicode_letter < 0x20) return false;
if(unicode_letter > 0xff && unicode_letter < 0xf000) return false;
// returning true with a box_h of 0 does not display an error
dsc_out->box_w = dsc_out->box_h = 0; // Prevents glyph not found error messages when true is returned
if(unicode_letter < 0x20) return true;
if(unicode_letter > 0xff && unicode_letter < 0xf000) return true;
// if(unicode_letter > 0xff) Serial.printf("Char# %u\n", unicode_letter);
// ulong startMillis = millis();
@ -439,7 +441,7 @@ bool IRAM_ATTR lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t * font, lv_font_
if(unicode_letter >= 0xF000) {
char filename[32];
sprintf_P(filename, PSTR("/fontawesome%u.zi"), fdsc->CharHeight);
if(!openFont(file, filename)) return false;
if(!openFont(file, filename)) return true; // suppress glyph not found errors for icon font
} else {
if(!openFont(file, (char *)font->user_data)) return false;
}

@ -1 +1 @@
Subproject commit 3953e9293adb8462265074d9769ef11fe218e29f
Subproject commit 994c62bf9a35d5e8e39ecfa496edc43c7e1ecbe9

View File

@ -16,11 +16,11 @@
extra_configs =
lcd_config.ini
pin_config.ini
; -- Put active [env] files in this dir to be included in the build menu
user_setups/*/*.ini
user_setups/active/*.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
@ -48,11 +48,11 @@ lib_deps =
https://github.com/netwizeBE/TFT_eSPI.git
;TFT_eSPI@^2.2.2 ; Tft SPI drivers
;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
PubSubClient@^2.8.0 ; MQTT client
ArduinoJson@^6.16.1 ; JSON Parser
StreamUtils@^1.4.0
Syslog@^2.0.0
AceButton@^1.4.0
AceButton@^1.6.1
;AsyncTCP
;https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip
;https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip
@ -68,9 +68,6 @@ build_flags =
-Og ; Code Debug Optimization
;-w ; Suppress warnings
-D CORE_DEBUG_LEVEL=1 ; Errors
-D HASP_VERSION_MAJOR=0
-D HASP_VERSION_MINOR=1
-D HASP_VERSION_REVISION=2
-D LV_CONF_INCLUDE_SIMPLE
-D LV_LVGL_H_INCLUDE_SIMPLE ; for lv_drivers
-D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files
@ -156,36 +153,12 @@ hspi32 =
; 7 - mirror content, and rotate 90 deg anti-clockwise
;***************************************************
; D1 Mini ESP32 with Lolin TFT 2.4"
;***************************************************
[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 = esp32_partition_app1280k_spiffs1472k.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)
lib_ignore =
GxTFT
XPT2046_Touchscreen
;***************************************************
; Lolin D32 Pro with Lolin TFT 2.4"
;***************************************************
; !! This board already defines TFT_CS, TFT_DC and TFT_RST !!
[env:lolind32pro-lolintft24]
platform = espressif32
platform = espressif32@^2.0.0
board = lolin_d32_pro
;upload_port = COM6 ; To change the port, use platform_override.ini
;monitor_port = COM6 ; To change the port, use platform_override.ini
@ -209,10 +182,10 @@ lib_ignore =
; D1 Mini ESP8266 with Lolin TFT 2.4"
;***************************************************
[env:d1mini-lolintft24]
platform = espressif8266@^2.4.0 ;@2.3.2
platform = espressif8266@^2.6.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
;upload_port = To change the port, use platform_override.ini
;monitor_port = 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
@ -237,25 +210,25 @@ lib_ignore =
;***************************************************
; Native build
;***************************************************
[env:native]
platform = native
build_flags =
-D LV_CONF_INCLUDE_SIMPLE
; -I src Required to find lv_conf.h
-I src
-I drivers/sdl2
-lSDL2
; SDL drivers options
-D LV_LVGL_H_INCLUDE_SIMPLE
-D LV_DRV_NO_CONF
-D USE_MONITOR
-D MONITOR_ZOOM=2
-D USE_MOUSE
-D USE_MOUSEWHEEL
-D USE_KEYBOARD
lib_deps =
;lvgl=https://github.com/littlevgl/lvgl/archive/master.zip
;lvgl@^6.1.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/master.zip
lv_drivers@^6.0.2
src_filter = +<*> +<../drivers/sdl2>
;[env:native]
;platform = native
;build_flags =
; -D LV_CONF_INCLUDE_SIMPLE
; ; -I src Required to find lv_conf.h
; -I src
; -I drivers/sdl2
; -lSDL2
; ; SDL drivers options
; -D LV_LVGL_H_INCLUDE_SIMPLE
; -D LV_DRV_NO_CONF
; -D USE_MONITOR
; -D MONITOR_ZOOM=2
; -D USE_MOUSE
; -D USE_MOUSEWHEEL
; -D USE_KEYBOARD
;lib_deps =
; ;lvgl=https://github.com/littlevgl/lvgl/archive/master.zip
; ;lvgl@^6.1.0
; ;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/master.zip
; lv_drivers@^6.0.2
;src_filter = +<*> +<../drivers/sdl2>

View File

@ -21,6 +21,7 @@
#include "hasp_attribute.h"
#include "hasp.h"
#include "lv_theme_hasp.h"
#include "EEPROM.h"
@ -55,7 +56,7 @@ char haspZiFontPath[32];
lv_style_t style_mbox_bg; /*Black bg. style with opacity*/
lv_obj_t * kb;
lv_font_t * defaultFont;
// lv_font_t * defaultFont;
#if LV_DEMO_WALLPAPER
LV_IMG_DECLARE(img_bubble_pattern)
@ -69,12 +70,9 @@ static const char * btnm_map2[] = {"0", "1", "\n", "2", "3", "\n", "4", "5",
*/
lv_obj_t * pages[HASP_NUM_PAGES];
#if defined(ARDUINO_ARCH_ESP8266)
static lv_font_t * haspFonts[4];
#else
lv_font_t * haspFonts[8];
#endif
uint8_t current_page = 0;
static lv_font_t * haspFonts[4] = {nullptr, LV_THEME_DEFAULT_FONT_NORMAL, LV_THEME_DEFAULT_FONT_SUBTITLE,
LV_THEME_DEFAULT_FONT_TITLE};
uint8_t current_page = 0;
/**********************
* MACROS
@ -85,6 +83,19 @@ uint8_t current_page = 0;
**********************/
void haspLoadPage(const char * pages);
////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Get Font ID
*/
lv_font_t * hasp_get_font(uint8_t fontid)
{
if(fontid >= 4) {
return nullptr;
} else {
return haspFonts[fontid];
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Get Page Object by PageID
@ -123,7 +134,8 @@ bool get_page_id(lv_obj_t * obj, uint8_t * pageid)
lv_obj_t * hasp_find_obj_from_id(lv_obj_t * parent, uint8_t objid)
{
if(objid == 0) return parent;
if(objid == 0 || parent == nullptr) return parent;
lv_obj_t * child;
child = lv_obj_get_child(parent, NULL);
while(child) {
@ -239,26 +251,13 @@ static inline void hasp_send_obj_attribute_txt(lv_obj_t * obj, const char * txt)
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload)
{
hasp_process_obj_attribute(hasp_find_obj_from_id(pageid, objid), attr, payload, strlen(payload) > 0);
/* else {
// publish the change
std::string strValue = "";
if(haspGetObjAttribute(obj, strAttr, strValue)) {
#if HASP_USE_MQTT > 0
mqtt_send_attribute(pageid, objid, strAttr.c_str(), strValue.c_str());
#endif
} else {
Log.warning(F("HASP: Unknown property: %s"), strAttr.c_str());
}
} // payload */
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Connection lost GUI
* WakeUp the display using a command instead of touch
*/
void haspWakeUp()
{
lv_disp_trig_activity(NULL);
@ -344,6 +343,19 @@ void haspProgressMsg(const __FlashStringHelper * msg)
haspProgressMsg(String(msg).c_str());
}
/*Add a custom apply callback*/
static void custom_font_apply_cb(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
{
lv_style_list_t * list;
switch(name) {
case LV_THEME_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
// _lv_style_list_add_style(list, &my_style);
break;
}
}
/**
* Create a demo application
*/
@ -351,12 +363,6 @@ void haspSetup()
{
guiSetDim(haspStartDim);
// lv_coord_t hres = lv_disp_get_hor_res(NULL);
// lv_coord_t vres = lv_disp_get_ver_res(NULL);
// static lv_font_t *
// my_font = (lv_font_t *)lv_mem_alloc(sizeof(lv_font_t));
/******* File System Test ********************************************************************/
lv_fs_file_t f;
lv_fs_res_t res;
@ -383,21 +389,23 @@ void haspSetup()
Log.error(F("Closing pages.json OK"));
else
Log.verbose(F("Closing pages.json on FS failed %d"), res);
/******* File System Test ********************************************************************/
/******* File System Test ********************************************************************/
/* ********** Font Initializations ********** */
/* ********** Font Initializations ********** */
defaultFont = LV_FONT_DEFAULT; // Use default font
#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
lv_zifont_init();
if(lv_zifont_font_init(&haspFonts[0], haspZiFontPath, 24) != 0) {
Log.error(F("HASP: Failed to set the custom font to %s"), haspZiFontPath);
if(lv_zifont_font_init(&haspFonts[0], haspZiFontPath, 32) != 0) {
Log.error(F("HASP: Failed to set font to %s"), haspZiFontPath);
haspFonts[0] = LV_FONT_DEFAULT;
} else {
defaultFont = haspFonts[0];
// defaultFont = haspFonts[0];
}
#endif
#endif
/* ********** Font Initializations ********** */
/* ********** Theme Initializations ********** */
@ -405,8 +413,8 @@ void haspSetup()
switch(haspThemeId) {
#if(LV_USE_THEME_EMPTY == 1)
case 0:
th = lv_theme_empty_init(LV_COLOR_PURPLE, LV_COLOR_BLACK, LV_THEME_DEFAULT_FLAGS, defaultFont, defaultFont,
defaultFont, defaultFont);
th = lv_theme_empty_init(LV_COLOR_PURPLE, LV_COLOR_BLACK, LV_THEME_DEFAULT_FLAGS, haspFonts[0], haspFonts[1],
haspFonts[2], haspFonts[3]);
break;
#endif
@ -424,15 +432,21 @@ void haspSetup()
#if(LV_USE_THEME_MONO == 1)
case 3:
th = lv_theme_mono_init(LV_COLOR_PURPLE, LV_COLOR_BLACK, LV_THEME_DEFAULT_FLAGS, defaultFont, defaultFont,
defaultFont, defaultFont);
th = lv_theme_mono_init(LV_COLOR_PURPLE, LV_COLOR_BLACK, LV_THEME_DEFAULT_FLAGS, haspFonts[0], haspFonts[1],
haspFonts[2], haspFonts[3]);
break;
#endif
#if LV_USE_THEME_MATERIAL == 1
case 4:
th = lv_theme_material_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE, LV_THEME_DEFAULT_FLAGS, defaultFont,
defaultFont, defaultFont, defaultFont);
th = lv_theme_material_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE,
LV_THEME_MATERIAL_FLAG_LIGHT + LV_THEME_MATERIAL_FLAG_NO_FOCUS, haspFonts[0],
haspFonts[1], haspFonts[2], haspFonts[3]);
break;
case 9:
th = lv_theme_material_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE,
LV_THEME_MATERIAL_FLAG_DARK + LV_THEME_MATERIAL_FLAG_NO_FOCUS, haspFonts[0],
haspFonts[1], haspFonts[2], haspFonts[3]);
break;
#endif
@ -450,15 +464,15 @@ void haspSetup()
#if LV_USE_THEME_TEMPLATE == 1
case 7:
th = lv_theme_template_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE, LV_THEME_DEFAULT_FLAGS, defaultFont,
defaultFont, defaultFont, defaultFont);
th = lv_theme_template_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE, LV_THEME_DEFAULT_FLAGS, haspFonts[0], haspFonts[1],
haspFonts[2], haspFonts[3]);
break;
#endif
#if(LV_USE_THEME_HASP == 1) || (LV_USE_THEME_TEMPLATE == 1)
#if(LV_USE_THEME_HASP == 1)
case 8:
th = lv_theme_template_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE, LV_THEME_DEFAULT_FLAGS, defaultFont,
defaultFont, defaultFont, defaultFont);
th = lv_theme_hasp_init(lv_color_hsv_to_rgb(haspThemeHue, 100, 100),
lv_color_hsv_to_rgb(haspThemeHue, 100, 100), LV_THEME_DEFAULT_FLAGS, haspFonts[0],
haspFonts[1], haspFonts[2], haspFonts[3]);
break;
#endif
@ -471,8 +485,8 @@ void haspSetup()
break;
*/
default:
th = lv_theme_material_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE, LV_THEME_DEFAULT_FLAGS, defaultFont,
defaultFont, defaultFont, defaultFont);
th = lv_theme_template_init(LV_COLOR_PURPLE, LV_COLOR_ORANGE, LV_THEME_DEFAULT_FLAGS, haspFonts[0],
haspFonts[1], haspFonts[2], haspFonts[3]);
Log.error(F("HASP: Unknown theme selected"));
}
@ -484,20 +498,19 @@ void haspSetup()
// lv_theme_set_current(th);
/* ********** Theme Initializations ********** */
lv_style_list_t * list;
static lv_style_t pagefont;
lv_style_init(&pagefont);
lv_style_set_text_font(&pagefont, LV_STATE_DEFAULT, defaultFont);
// lv_style_list_t * list;
// static lv_style_t pagefont;
// lv_style_init(&pagefont);
// lv_style_set_text_font(&pagefont, LV_STATE_DEFAULT, defaultFont);
list = lv_obj_get_style_list(lv_disp_get_layer_top(NULL), LV_OBJ_PART_MAIN);
_lv_style_list_add_style(list, &pagefont);
// list = lv_obj_get_style_list(lv_disp_get_layer_top(NULL), LV_OBJ_PART_MAIN);
// _lv_style_list_add_style(list, &pagefont);
/* Create all screens using the theme */
for(uint8_t i = 0; i < (sizeof pages / sizeof *pages); i++) {
pages[i] = lv_obj_create(NULL, NULL);
list = lv_obj_get_style_list(pages[i], LV_OBJ_PART_MAIN);
_lv_style_list_add_style(list, &pagefont);
// lv_obj_set_size(pages[0], hres, vres);
// list = lv_obj_get_style_list(pages[i], LV_OBJ_PART_MAIN);
// _lv_style_list_add_style(list, &pagefont);
}
#if HASP_USE_WIFI > 0
@ -711,10 +724,10 @@ String haspGetVersion()
void haspClearPage(uint16_t pageid)
{
lv_obj_t * page = get_page_obj(pageid);
if(!page) {
if(!page || pageid > 255) {
Log.warning(F("HASP: Page ID %u not defined"), pageid);
} else if(page == lv_layer_sys() || page == lv_layer_top()) {
Log.warning(F("HASP: Cannot clear a layer"));
} else if(page == lv_layer_sys() /*|| page == lv_layer_top()*/) {
Log.warning(F("HASP: Cannot clear system layer"));
} else {
Log.notice(F("HASP: Clearing page %u"), pageid);
lv_obj_clean(pages[pageid]);
@ -787,7 +800,6 @@ void haspNewObject(const JsonObject & config, uint8_t & saved_page_id)
}
}
/* Input cache and validation */
uint8_t objid = config[F("objid")].as<uint8_t>();
uint8_t id = config[F("id")].as<uint8_t>();
@ -802,9 +814,7 @@ void haspNewObject(const JsonObject & config, uint8_t & saved_page_id)
/* ----- Basic Objects ------ */
case LV_HASP_BUTTON: {
obj = lv_btn_create(parent_obj, NULL);
/* lv_obj_t * label ; */
lv_label_create(obj, NULL);
// haspSetOpacity(obj, LV_OPA_COVER);
lv_obj_set_event_cb(obj, btn_event_handler);
break;
}
@ -931,8 +941,7 @@ void haspNewObject(const JsonObject & config, uint8_t & saved_page_id)
break;
}
case LV_HASP_ROLLER: {
obj = lv_roller_create(parent_obj, NULL);
bool infinite = config[F("infinite")].as<bool>();
obj = lv_roller_create(parent_obj, NULL);
// lv_roller_set_fix_width(obj, width);
// lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
lv_obj_set_event_cb(obj, roller_event_handler);
@ -1004,7 +1013,7 @@ void haspLoadPage(const char * pages)
Log.notice(F("HASP: Loading file %s"), pages);
File file = SPIFFS.open(pages, "r");
dispatchJsonl(file);
dispatchParseJsonl(file);
file.close();
Log.notice(F("HASP: File %s loaded"), pages);

View File

@ -106,6 +106,7 @@ bool haspGetConfig(const JsonObject & settings);
bool haspSetConfig(const JsonObject & settings);
lv_obj_t * hasp_find_obj_from_id(lv_obj_t * parent, uint8_t objid);
lv_font_t * hasp_get_font(uint8_t fontid);
void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event);
void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event);

View File

@ -1,50 +0,0 @@
#include "lvgl.h"
#include "hasp.h"
#include "hasp_attribute.h"
//#include "hasp_attr_get.h"
#define LVGL7 1
bool haspGetObjAttribute(lv_obj_t * obj, String strAttr, std::string & strPayload)
{
if(!obj) return false;
switch(strAttr.length()) {
case 4:
/* .txt and .val depend on objecttype */
lv_obj_type_t list;
lv_obj_get_type(obj, &list);
if(strAttr == F(".val")) {
if(check_obj_type(list.type[0], LV_HASP_PRELOADER)) return false;
if(check_obj_type(list.type[0], LV_HASP_BUTTON)) {
if(lv_btn_get_state(obj) == LV_BTN_STATE_CHECKED_PRESSED ||
lv_btn_get_state(obj) == LV_BTN_STATE_CHECKED_RELEASED)
strPayload = "1"; // It's toggled
else
strPayload = "0"; // Normal btn has no toggle state
}
if(check_obj_type(list.type[0], LV_HASP_SLIDER)) strPayload = String(lv_slider_get_value(obj)).c_str();
if(check_obj_type(list.type[0], LV_HASP_GAUGE)) strPayload = String(lv_gauge_get_value(obj, 0)).c_str();
if(check_obj_type(list.type[0], LV_HASP_BAR)) strPayload = String(lv_bar_get_value(obj)).c_str();
if(check_obj_type(list.type[0], LV_HASP_LMETER))
strPayload = String(lv_linemeter_get_value(obj)).c_str();
// if(check_obj_type(list.type[0], LV_HASP_CPICKER)) strPayload =
// String(lv_cpicker_get_color(obj)).c_str();
if(check_obj_type(list.type[0], LV_HASP_CHECKBOX))
strPayload = String(!lv_checkbox_is_checked(obj) ? 0 : 1).c_str();
if(check_obj_type(list.type[0], LV_HASP_DDLIST))
strPayload = String(lv_dropdown_get_selected(obj)).c_str();
if(check_obj_type(list.type[0], LV_HASP_ROLLER))
strPayload = String(lv_roller_get_selected(obj)).c_str();
if(check_obj_type(list.type[0], LV_HASP_LED)) strPayload = String(lv_led_get_bright(obj)).c_str();
if(check_obj_type(list.type[0], LV_HASP_SWITCH)) strPayload = String(lv_switch_get_state(obj)).c_str();
}
}
return false;
}

View File

@ -11,7 +11,7 @@
LV_FONT_DECLARE(unscii_8_icon);
extern lv_font_t * haspFonts[8];
static inline bool is_true(const char * s);
static bool is_true(const char * s);
static inline bool only_digits(const char * s);
/* 16-bit hashing function http://www.cse.yorku.ca/~oz/hash.html */
@ -57,32 +57,32 @@ static lv_color_t haspPayloadToColor(const char * payload)
{
switch(strlen(payload)) {
case 3:
if(!strcmp_P(payload, PSTR("red"))) return haspLogColor(LV_COLOR_RED);
if(!strcasecmp_P(payload, PSTR("red"))) return haspLogColor(LV_COLOR_RED);
break;
case 4:
if(!strcmp_P(payload, PSTR("blue"))) return haspLogColor(LV_COLOR_BLUE);
if(!strcmp_P(payload, PSTR("cyan"))) return haspLogColor(LV_COLOR_CYAN);
if(!strcmp_P(payload, PSTR("gray"))) return haspLogColor(LV_COLOR_GRAY);
/* if(!strcmp_P(payload, PSTR("aqua"))) return haspLogColor(LV_COLOR_AQUA);
if(!strcmp_P(payload, PSTR("lime"))) return haspLogColor(LV_COLOR_LIME);
if(!strcmp_P(payload, PSTR("teal"))) return haspLogColor(LV_COLOR_TEAL);
if(!strcmp_P(payload, PSTR("navy"))) return haspLogColor(LV_COLOR_NAVY);*/
if(!strcasecmp_P(payload, PSTR("blue"))) return haspLogColor(LV_COLOR_BLUE);
if(!strcasecmp_P(payload, PSTR("cyan"))) return haspLogColor(LV_COLOR_CYAN);
if(!strcasecmp_P(payload, PSTR("gray"))) return haspLogColor(LV_COLOR_GRAY);
// if(!strcmp_P(payload, PSTR("aqua"))) return haspLogColor(LV_COLOR_AQUA);
// if(!strcmp_P(payload, PSTR("lime"))) return haspLogColor(LV_COLOR_LIME);
// if(!strcmp_P(payload, PSTR("teal"))) return haspLogColor(LV_COLOR_TEAL);
// if(!strcmp_P(payload, PSTR("navy"))) return haspLogColor(LV_COLOR_NAVY);
break;
case 5:
if(!strcmp_P(payload, PSTR("green"))) return haspLogColor(LV_COLOR_GREEN);
if(!strcmp_P(payload, PSTR("white"))) return haspLogColor(LV_COLOR_WHITE);
if(!strcmp_P(payload, PSTR("black"))) return haspLogColor(LV_COLOR_BLACK);
if(!strcasecmp_P(payload, PSTR("green"))) return haspLogColor(LV_COLOR_GREEN);
if(!strcasecmp_P(payload, PSTR("white"))) return haspLogColor(LV_COLOR_WHITE);
if(!strcasecmp_P(payload, PSTR("black"))) return haspLogColor(LV_COLOR_BLACK);
// if(!strcmp_P(payload, PSTR("olive"))) return haspLogColor(LV_COLOR_OLIVE);
break;
case 6:
if(!strcmp_P(payload, PSTR("yellow"))) return haspLogColor(LV_COLOR_YELLOW);
if(!strcmp_P(payload, PSTR("orange"))) return haspLogColor(LV_COLOR_ORANGE);
if(!strcmp_P(payload, PSTR("purple"))) return haspLogColor(LV_COLOR_PURPLE);
if(!strcmp_P(payload, PSTR("silver"))) return haspLogColor(LV_COLOR_SILVER);
if(!strcasecmp_P(payload, PSTR("yellow"))) return haspLogColor(LV_COLOR_YELLOW);
if(!strcasecmp_P(payload, PSTR("orange"))) return haspLogColor(LV_COLOR_ORANGE);
if(!strcasecmp_P(payload, PSTR("purple"))) return haspLogColor(LV_COLOR_PURPLE);
if(!strcasecmp_P(payload, PSTR("silver"))) return haspLogColor(LV_COLOR_SILVER);
// if(!strcmp_P(payload, PSTR("maroon"))) return haspLogColor(LV_COLOR_MAROON);
break;
case 7:
if(!strcmp_P(payload, PSTR("magenta"))) return haspLogColor(LV_COLOR_MAGENTA);
if(!strcasecmp_P(payload, PSTR("magenta"))) return haspLogColor(LV_COLOR_MAGENTA);
default:
// if(!strcmp_P(payload, PSTR("darkblue"))) return haspLogColor(LV_COLOR_MAKE(0, 51, 102));
@ -118,19 +118,49 @@ static lv_color_t haspPayloadToColor(const char * payload)
return LV_COLOR_BLACK;
}
static lv_font_t * haspPayloadToFont(const char * payload)
{
uint8_t var = atoi(payload);
switch(var) {
case 0:
case 1:
case 2:
case 3:
return hasp_get_font(var);
case 8:
return &unscii_8_icon;
#if ESP32
case 12:
return &lv_font_montserrat_12;
case 16:
return &lv_font_montserrat_16;
case 22:
return &lv_font_montserrat_22;
case 28:
return &lv_font_montserrat_28_compressed;
#endif
default:
return nullptr;
}
}
static void hasp_process_label_long_mode(lv_obj_t * obj, const char * payload, bool update)
{
if(update) {
lv_label_long_mode_t mode = LV_LABEL_LONG_EXPAND;
if(!strcmp_P(payload, PSTR("expand"))) {
if(!strcasecmp_P(payload, PSTR("expand"))) {
mode = LV_LABEL_LONG_EXPAND;
} else if(!strcmp_P(payload, PSTR("break"))) {
} else if(!strcasecmp_P(payload, PSTR("break"))) {
mode = LV_LABEL_LONG_BREAK;
} else if(!strcmp_P(payload, PSTR("dots"))) {
} else if(!strcasecmp_P(payload, PSTR("dots"))) {
mode = LV_LABEL_LONG_DOT;
} else if(!strcmp_P(payload, PSTR("scroll"))) {
} else if(!strcasecmp_P(payload, PSTR("scroll"))) {
mode = LV_LABEL_LONG_SROLL;
} else if(!strcmp_P(payload, PSTR("loop"))) {
} else if(!strcasecmp_P(payload, PSTR("loop"))) {
mode = LV_LABEL_LONG_SROLL_CIRC;
} else {
return Log.warning(F("Invalid long mode"));
@ -202,60 +232,142 @@ static void hasp_attribute_get_part_state(lv_obj_t * obj, const char * attr_in,
uint8_t & state)
{
int len = strlen(attr_in);
if(len > 0 && len < 32) {
// Check Trailing partnumber
if(attr_in[len - 1] == '1') {
part = LV_TABLE_PART_CELL1;
} else if(attr_in[len - 1] == '2') {
part = LV_TABLE_PART_CELL2;
} else if(attr_in[len - 1] == '3') {
part = LV_TABLE_PART_CELL3;
} else if(attr_in[len - 1] == '4') {
part = LV_TABLE_PART_CELL4;
}
if(len <= 0 || len >= 32) {
attr_out[0] = 0; // empty string
part = LV_OBJ_PART_MAIN;
state = LV_STATE_DEFAULT;
return;
}
int index = atoi(&attr_in[len - 1]);
// Remove Trailing part digit
if(part != LV_TABLE_PART_BG && len > 0) {
len--;
// Drop Trailing partnumber
if(attr_in[len - 1] == '0' || index > 0) {
part = LV_TABLE_PART_BG;
len--;
}
strncpy(attr_out, attr_in, len);
attr_out[len] = 0;
/* Attributes depending on objecttype */
lv_obj_type_t list;
lv_obj_get_type(obj, &list);
const char * objtype = list.type[0];
if(check_obj_type(objtype, LV_HASP_BUTTON)) {
switch(index) {
case 1:
state = LV_BTN_STATE_PRESSED;
break;
case 2:
state = LV_BTN_STATE_DISABLED;
break;
case 3:
state = LV_BTN_STATE_CHECKED_RELEASED;
break;
case 4:
state = LV_BTN_STATE_CHECKED_PRESSED;
break;
case 5:
state = LV_BTN_STATE_CHECKED_DISABLED;
break;
default:
state = LV_BTN_STATE_RELEASED;
}
strncpy(attr_out, attr_in, len + 1);
attr_out[len] = 0;
} else {
attr_out[0] = 0;
part = LV_BTN_PART_MAIN;
return;
}
if(check_obj_type(objtype, LV_HASP_BAR)) {
if(index == 1) {
part = LV_BAR_PART_INDIC;
} else {
part = LV_BAR_PART_BG;
}
state = LV_STATE_DEFAULT;
return;
}
if(check_obj_type(objtype, LV_HASP_CHECKBOX)) {
if(index == 1) {
part = LV_CHECKBOX_PART_BULLET;
} else {
part = LV_CHECKBOX_PART_BG;
}
state = LV_STATE_DEFAULT;
return;
}
if(check_obj_type(objtype, LV_HASP_CPICKER)) {
if(index == 1) {
part = LV_CPICKER_PART_KNOB;
} else {
part = LV_CPICKER_PART_MAIN;
}
state = LV_STATE_DEFAULT;
return;
}
}
/**
* Change or Retrieve the value of a local attribute of an object PART
* @param obj lv_obj_t*: the object to get/set the attribute
* @param attr_p char*: the attribute name (with or without leading ".")
* @param attr_hash uint16_t: the sbdm hash of the attribute name without leading "."
* @param payload char*: the new value of the attribute
* @param update bool: change/set the value if true, dispatch/get value if false
* @note setting a value won't return anything, getting will dispatch the value
*/
static void hasp_local_style_attr(lv_obj_t * obj, const char * attr_p, uint16_t attr_hash, const char * payload,
bool update)
{
char attr[32];
uint8_t part = LV_TABLE_PART_BG;
uint8_t part = LV_OBJ_PART_MAIN;
uint8_t state = LV_STATE_DEFAULT;
int16_t var = atoi(payload);
hasp_attribute_get_part_state(obj, attr_p, attr, part, state);
attr_hash = sdbm(attr); // attribute name without the index number
/* ***** WARNING ****************************************************
* when using hasp_out use attr_p for the original attribute name
* *************************************************************** */
switch(attr_hash) {
/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/
#if LV_USE_BLEND_MODES
case ATTR_BG_BLEND_MODE:
return attribute_bg_blend_mode(obj, part, state, update, attr_p, (lv_blend_mode_t)var);
case ATTR_TEXT_BLEND_MODE:
return lv_obj_set_style_local_text_blend_mode(obj, part, state, (lv_blend_mode_t)var);
case ATTR_BORDER_BLEND_MODE:
return lv_obj_set_style_local_border_blend_mode(obj, part, state, (lv_blend_mode_t)var);
case ATTR_OUTLINE_BLEND_MODE:
return lv_obj_set_style_local_outline_blend_mode(obj, part, state, (lv_blend_mode_t)var);
case ATTR_SHADOW_BLEND_MODE:
return lv_obj_set_style_local_shadow_blend_mode(obj, part, state, (lv_blend_mode_t)var);
case ATTR_LINE_BLEND_MODE:
return lv_obj_set_style_local_line_blend_mode(obj, part, state, (lv_blend_mode_t)var);
case ATTR_VALUE_BLEND_MODE:
return lv_obj_set_style_local_value_blend_mode(obj, part, state, (lv_blend_mode_t)var);
case ATTR_PATTERN_BLEND_MODE:
return lv_obj_set_style_local_pattern_blend_mode(obj, part, state, (lv_blend_mode_t)var);
#endif
case ATTR_SIZE:
return attribute_size(obj, part, state, update, attr_p, var);
case ATTR_RADIUS:
return attribute_radius(obj, part, state, update, attr_p, var);
case ATTR_CLIP_CORNER:
return attribute_clip_corner(obj, part, state, update, attr_p, var);
case ATTR_SIZE:
return attribute_size(obj, part, state, update, attr_p, var);
case ATTR_TRANSFORM_WIDTH:
return lv_obj_set_style_local_transform_width(obj, part, state, (lv_style_int_t)var);
case ATTR_TRANSFORM_HEIGHT:
return lv_obj_set_style_local_transform_height(obj, part, state, (lv_style_int_t)var);
case ATTR_OPA_SCALE:
return lv_obj_set_style_local_opa_scale(obj, part, state, (lv_opa_t)var);
return attribute_opa_scale(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_TRANSFORM_WIDTH:
return attribute_transform_width(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_TRANSFORM_HEIGHT:
return attribute_transform_height(obj, part, state, update, attr_p, (lv_style_int_t)var);
/* Background attributes */
case ATTR_BG_BLEND_MODE:
return attribute_bg_blend_mode(obj, part, state, update, attr_p, (lv_blend_mode_t)var);
/* Background attributes */
case ATTR_BG_MAIN_STOP:
return attribute_bg_main_stop(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_BG_GRAD_STOP:
@ -276,25 +388,25 @@ static void hasp_local_style_attr(lv_obj_t * obj, const char * attr_p, uint16_t
/* Padding attributes */
case ATTR_PAD_TOP:
return attribute_pad_top(obj, part, state, update, attr_p, (lv_blend_mode_t)var);
return attribute_pad_top(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_PAD_BOTTOM:
return attribute_pad_bottom(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_PAD_LEFT:
return attribute_pad_left(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_PAD_RIGHT:
return attribute_pad_right(obj, part, state, update, attr_p, (lv_grad_dir_t)var);
return attribute_pad_right(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_PAD_INNER:
return attribute_pad_inner(obj, part, state, update, attr_p, (lv_opa_t)var);
return attribute_pad_inner(obj, part, state, update, attr_p, (lv_style_int_t)var);
/* Text attributes */
case ATTR_TEXT_LETTER_SPACE:
return lv_obj_set_style_local_text_letter_space(obj, part, state, (lv_style_int_t)var);
return attribute_text_letter_space(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_TEXT_LINE_SPACE:
return lv_obj_set_style_local_text_line_space(obj, part, state, (lv_style_int_t)var);
return attribute_text_line_space(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_TEXT_DECOR:
return lv_obj_set_style_local_text_decor(obj, part, state, (lv_text_decor_t)var);
case ATTR_TEXT_BLEND_MODE:
return lv_obj_set_style_local_text_blend_mode(obj, part, state, (lv_blend_mode_t)var);
return attribute_text_decor(obj, part, state, update, attr_p, (lv_text_decor_t)var);
case ATTR_TEXT_OPA:
return attribute_text_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_TEXT_COLOR: {
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_text_color(obj, part, state, color);
@ -303,210 +415,149 @@ static void hasp_local_style_attr(lv_obj_t * obj, const char * attr_p, uint16_t
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_text_sel_color(obj, part, state, color);
}
case ATTR_TEXT_OPA:
return lv_obj_set_style_local_text_opa(obj, part, state, (lv_opa_t)var);
case ATTR_TEXT_FONT: {
lv_font_t * font = haspPayloadToFont(payload);
if(font) {
return lv_obj_set_style_local_text_font(obj, part, state, font);
} else {
return Log.warning(F("HASP: Unknown Font ID %s"), payload);
}
}
/* Border attributes */
case ATTR_BORDER_WIDTH:
return lv_obj_set_style_local_border_width(obj, part, state, (lv_style_int_t)var);
return attribute_border_width(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_BORDER_SIDE:
return lv_obj_set_style_local_border_side(obj, part, state, (lv_border_side_t)var);
case ATTR_BORDER_BLEND_MODE:
return lv_obj_set_style_local_border_blend_mode(obj, part, state, (lv_blend_mode_t)var);
return attribute_border_side(obj, part, state, update, attr_p, (lv_border_side_t)var);
case ATTR_BORDER_POST:
return lv_obj_set_style_local_border_post(obj, part, state, (bool)var);
return attribute_border_post(obj, part, state, update, attr_p, is_true(payload));
case ATTR_BORDER_OPA:
return attribute_border_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_BORDER_COLOR: {
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_border_color(obj, part, state, color);
}
case ATTR_BORDER_OPA:
return lv_obj_set_style_local_border_opa(obj, part, state, (lv_opa_t)var);
/* Outline attributes */
/* Outline attributes */
case ATTR_OUTLINE_WIDTH:
return lv_obj_set_style_local_outline_width(obj, part, state, (lv_style_int_t)var);
return attribute_outline_width(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_OUTLINE_PAD:
return lv_obj_set_style_local_outline_pad(obj, part, state, (lv_style_int_t)var);
case ATTR_OUTLINE_BLEND_MODE:
return lv_obj_set_style_local_outline_blend_mode(obj, part, state, (lv_blend_mode_t)var);
return attribute_outline_pad(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_OUTLINE_OPA:
return attribute_outline_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_OUTLINE_COLOR: {
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_outline_color(obj, part, state, color);
}
case ATTR_OUTLINE_OPA:
return lv_obj_set_style_local_outline_opa(obj, part, state, (lv_opa_t)var);
/* Shadow attributes */
#if LV_USE_SHADOW
case ATTR_SHADOW_WIDTH:
return lv_obj_set_style_local_shadow_width(obj, part, state, (lv_style_int_t)var);
return attribute_shadow_width(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_SHADOW_OFS_X:
return lv_obj_set_style_local_shadow_ofs_x(obj, part, state, (lv_style_int_t)var);
return attribute_shadow_ofs_x(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_SHADOW_OFS_Y:
return lv_obj_set_style_local_shadow_ofs_y(obj, part, state, (lv_style_int_t)var);
return attribute_shadow_ofs_y(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_SHADOW_SPREAD:
return lv_obj_set_style_local_shadow_spread(obj, part, state, (lv_style_int_t)var);
case ATTR_SHADOW_BLEND_MODE:
return lv_obj_set_style_local_shadow_blend_mode(obj, part, state, (lv_blend_mode_t)var);
return attribute_shadow_spread(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_SHADOW_OPA:
return attribute_shadow_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_SHADOW_COLOR: {
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_shadow_color(obj, part, state, color);
}
case ATTR_SHADOW_OPA:
return lv_obj_set_style_local_shadow_opa(obj, part, state, (lv_opa_t)var);
#endif
/* Line attributes */
case ATTR_LINE_WIDTH:
return lv_obj_set_style_local_line_width(obj, part, state, (lv_style_int_t)var);
case ATTR_LINE_BLEND_MODE:
return lv_obj_set_style_local_line_blend_mode(obj, part, state, (lv_blend_mode_t)var);
return attribute_line_width(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_LINE_DASH_WIDTH:
return lv_obj_set_style_local_line_dash_width(obj, part, state, (lv_style_int_t)var);
return attribute_line_dash_width(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_LINE_DASH_GAP:
return lv_obj_set_style_local_line_dash_gap(obj, part, state, (lv_style_int_t)var);
return attribute_line_dash_gap(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_LINE_ROUNDED:
return lv_obj_set_style_local_line_rounded(obj, part, state, (bool)var);
return attribute_line_rounded(obj, part, state, update, attr_p, is_true(payload));
case ATTR_LINE_OPA:
return attribute_line_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_LINE_COLOR: {
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_line_color(obj, part, state, color);
}
case ATTR_LINE_OPA:
return lv_obj_set_style_local_line_opa(obj, part, state, (lv_opa_t)var);
/* Value attributes */
case ATTR_VALUE_LETTER_SPACE:
return lv_obj_set_style_local_value_letter_space(obj, part, state, (lv_style_int_t)var);
return attribute_value_letter_space(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_VALUE_LINE_SPACE:
return lv_obj_set_style_local_value_line_space(obj, part, state, (lv_style_int_t)var);
case ATTR_VALUE_BLEND_MODE:
return lv_obj_set_style_local_value_blend_mode(obj, part, state, (lv_blend_mode_t)var);
return attribute_value_line_space(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_VALUE_OFS_X:
return lv_obj_set_style_local_value_ofs_x(obj, part, state, (lv_style_int_t)var);
return attribute_value_ofs_x(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_VALUE_OFS_Y:
return lv_obj_set_style_local_value_ofs_y(obj, part, state, (lv_style_int_t)var);
return attribute_value_ofs_y(obj, part, state, update, attr_p, (lv_style_int_t)var);
case ATTR_VALUE_ALIGN:
return lv_obj_set_style_local_value_align(obj, part, state, (lv_align_t)var);
return attribute_value_align(obj, part, state, update, attr_p, (lv_align_t)var);
case ATTR_VALUE_OPA:
return attribute_value_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_VALUE_STR: {
if(update) {
// Free previous string
const char * str = lv_obj_get_style_value_str(obj, part);
lv_obj_set_style_local_value_str(obj, part, state, NULL);
lv_mem_free(str);
// Create new string
size_t len = strlen(payload);
if(len > 0) {
len++;
char * str_p = (char *)lv_mem_alloc(len);
memset(str_p, 0, len);
memccpy(str_p, payload, 0, len);
lv_obj_set_style_local_value_str(obj, part, state, str_p);
}
} else {
hasp_out_str(obj, attr, lv_obj_get_style_value_str(obj, part));
}
return;
}
case ATTR_VALUE_COLOR: {
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_value_color(obj, part, state, color);
}
case ATTR_VALUE_OPA:
return lv_obj_set_style_local_value_opa(obj, part, state, (lv_opa_t)var);
case ATTR_VALUE_STR:
return lv_obj_set_style_local_value_str(obj, part, state, (const char *)payload);
case ATTR_VALUE_FONT: {
lv_font_t * font = haspPayloadToFont(payload);
if(font) {
return lv_obj_set_style_local_value_font(obj, part, state, font);
} else {
return Log.warning(F("HASP: Unknown Font ID %s"), attr_p);
}
}
/* Pattern attributes */
case ATTR_PATTERN_REPEAT:
return lv_obj_set_style_local_pattern_repeat(obj, part, state, (bool)var);
case ATTR_PATTERN_BLEND_MODE:
return lv_obj_set_style_local_pattern_blend_mode(obj, part, state, (lv_blend_mode_t)var);
return attribute_pattern_repeat(obj, part, state, update, attr_p, is_true(payload));
case ATTR_PATTERN_OPA:
return attribute_pattern_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_PATTERN_RECOLOR_OPA:
return attribute_pattern_recolor_opa(obj, part, state, update, attr_p, (lv_opa_t)var);
case ATTR_PATTERN_IMAGE:
// return lv_obj_set_style_local_pattern_image(obj, part, state, (constvoid *)var);
break;
case ATTR_PATTERN_RECOLOR: {
lv_color_t color = haspPayloadToColor(payload);
return lv_obj_set_style_local_pattern_recolor(obj, part, state, color);
}
case ATTR_PATTERN_OPA:
return lv_obj_set_style_local_pattern_opa(obj, part, state, (lv_opa_t)var);
case ATTR_PATTERN_RECOLOR_OPA:
return lv_obj_set_style_local_pattern_recolor_opa(obj, part, state, (lv_opa_t)var);
case ATTR_PATTERN_IMAGE:
// return lv_obj_set_style_local_pattern_image(obj, part, state, (constvoid *)var);
break;
/* Image attributes */
// Todo
/* Scale attributes */
// Todo
/* Transition attributes */
// Todo
}
Log.warning(F("HASP: Unknown property %s"), attr_p);
}
static void hasp_local_style_attr_font(lv_obj_t * obj, const char * attr_p, uint16_t attr_hash, const char * payload,
bool update)
{
uint8_t part = LV_TABLE_PART_BG;
uint8_t state = LV_STATE_DEFAULT;
int16_t var = atoi(payload);
int len = strlen(attr_p);
if(len > 0 && len < 32) {
// Check Trailing partnumber
if(attr_p[len - 1] == '1') {
part = LV_TABLE_PART_CELL1;
} else if(attr_p[len - 1] == '2') {
part = LV_TABLE_PART_CELL2;
} else if(attr_p[len - 1] == '3') {
part = LV_TABLE_PART_CELL3;
} else if(attr_p[len - 1] == '4') {
part = LV_TABLE_PART_CELL4;
// } else if(attr[len - 1] == '9') {
// part = LV_PAGE_PART_SCROLLBAR;
}
// Remove Trailing part digit
char attr[32];
if(part != LV_TABLE_PART_BG && len > 0) {
len--;
}
strncpy(attr, attr_p, len + 1);
attr[len] = 0;
// debugPrintln(strAttr + "&" + part);
/* ***** WARNING ****************************************************
* when using hasp_out use attr_p for the original attribute name
* *************************************************************** */
if(!strcmp_P(attr, PSTR("value_font"))) {
#if ESP32
switch(var) {
case 8:
lv_obj_set_style_local_value_font(obj, part, state, &unscii_8_icon);
break;
case 12:
lv_obj_set_style_local_value_font(obj, part, state, &lv_font_montserrat_12);
break;
case 16:
lv_obj_set_style_local_value_font(obj, part, state, &lv_font_montserrat_16);
break;
case 22:
lv_obj_set_style_local_value_font(obj, part, state, &lv_font_montserrat_22);
break;
case 28:
lv_obj_set_style_local_value_font(obj, part, state, &lv_font_montserrat_28_compressed);
break;
}
return;
#endif
// return lv_obj_set_style_local_value_font(obj, part, state, (constlv_font_t *)var);
} else if(!strcmp_P(attr, PSTR("text_font"))) {
#if ESP32
switch(var) {
case 0:
lv_obj_set_style_local_text_font(obj, part, state, haspFonts[0]);
Log.verbose(F("Changing font to : %s"), (char *)haspFonts[0]->user_data);
break;
case 8:
lv_obj_set_style_local_text_font(obj, part, state, &unscii_8_icon);
break;
case 12:
lv_obj_set_style_local_text_font(obj, part, state, &lv_font_montserrat_12);
break;
case 16:
lv_obj_set_style_local_text_font(obj, part, state, &lv_font_montserrat_16);
break;
case 22:
lv_obj_set_style_local_text_font(obj, part, state, &lv_font_montserrat_22);
break;
case 28:
lv_obj_set_style_local_text_font(obj, part, state, &lv_font_montserrat_28_compressed);
break;
}
return;
#endif
// return lv_obj_set_style_local_text_font(obj, part, state, (constlv_font_t *)var);
}
}
Log.warning(F("HASP: Unknown property %s"), attr_p);
}
// OK
static void hasp_process_obj_attribute_txt(lv_obj_t * obj, const char * attr, const char * payload, bool update)
{
@ -552,8 +603,8 @@ static void hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, co
lv_obj_get_type(obj, &list);
const char * objtype = list.type[0];
if(check_obj_type(objtype, LV_HASP_BUTTON)) {
if(lv_btn_get_checkable(obj)) {
if(check_obj_type(objtype, LV_HASP_BUTTON) && lv_btn_get_checkable(obj)) {
if(update) {
lv_btn_state_t state;
switch(val) {
case 0:
@ -562,16 +613,34 @@ static void hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, co
case 1:
state = LV_BTN_STATE_CHECKED_RELEASED;
break;
case 3:
state = LV_BTN_STATE_CHECKED_DISABLED;
break;
default:
state = LV_BTN_STATE_DISABLED;
};
return lv_btn_set_state(obj, state);
} else {
lv_btn_state_t state = lv_btn_get_state(obj);
switch(state) {
case LV_BTN_STATE_RELEASED:
case LV_BTN_STATE_PRESSED:
return hasp_out_int(obj, attr, 0);
case LV_BTN_STATE_CHECKED_RELEASED:
case LV_BTN_STATE_CHECKED_PRESSED:
return hasp_out_int(obj, attr, 1);
case LV_BTN_STATE_DISABLED:
return hasp_out_int(obj, attr, 2);
case LV_BTN_STATE_CHECKED_DISABLED:
return hasp_out_int(obj, attr, 3);
}
lv_btn_set_state(obj, state);
return;
}
}
if(check_obj_type(objtype, LV_HASP_CHECKBOX)) {
return update ? lv_checkbox_set_checked(obj, is_true(payload))
: hasp_out_int(obj, attr, lv_checkbox_is_checked(obj));
}
if(check_obj_type(objtype, LV_HASP_SWITCH)) {
if(update) {
@ -579,23 +648,34 @@ static void hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, co
} else {
return hasp_out_int(obj, attr, lv_switch_get_state(obj));
}
} else if(check_obj_type(objtype, LV_HASP_DDLIST)) {
lv_dropdown_set_selected(obj, val);
return;
} else if(check_obj_type(objtype, LV_HASP_LMETER)) {
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)) {
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)) {
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_ARC)) {
return update ? lv_arc_set_value(obj, intval) : hasp_out_int(obj, attr, lv_arc_get_value(obj));
} else if(check_obj_type(objtype, LV_HASP_GAUGE)) {
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)) {
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));
@ -616,32 +696,53 @@ static void hasp_process_obj_attribute_range(lv_obj_t * obj, const char * attr,
if(check_obj_type(objtype, LV_HASP_SLIDER)) {
int16_t min = lv_slider_get_min_value(obj);
int16_t max = lv_slider_get_max_value(obj);
if(update && (set_min ? val : min) >= (set_max ? val : max)) return; // prevent setting min>=max
return update ? lv_slider_set_range(obj, set_min ? val : min, set_max ? val : max)
: hasp_out_int(obj, attr, set_min ? lv_slider_get_min_value(obj) : lv_slider_get_max_value(obj));
}
if(check_obj_type(objtype, LV_HASP_GAUGE)) {
int16_t min = lv_gauge_get_min_value(obj);
int16_t max = lv_gauge_get_max_value(obj);
if(update && (set_min ? val : min) >= (set_max ? val : max)) return; // prevent setting min>=max
return update ? lv_gauge_set_range(obj, set_min ? val : min, set_max ? val : max)
: hasp_out_int(obj, attr, set_min ? lv_gauge_get_min_value(obj) : lv_gauge_get_max_value(obj));
}
if(check_obj_type(objtype, LV_HASP_ARC)) {
int16_t min = lv_arc_get_min_value(obj);
int16_t max = lv_arc_get_max_value(obj);
if(update && (set_min ? val : min) >= (set_max ? val : max)) return; // prevent setting min>=max
return update ? lv_arc_set_range(obj, set_min ? val : min, set_max ? val : max)
: hasp_out_int(obj, attr, set_min ? lv_arc_get_min_value(obj) : lv_arc_get_max_value(obj));
}
if(check_obj_type(objtype, LV_HASP_BAR)) {
int16_t min = lv_bar_get_min_value(obj);
int16_t max = lv_bar_get_max_value(obj);
if(update && (set_min ? val : min) >= (set_max ? val : max)) return; // prevent setting min>=max
return update ? lv_bar_set_range(obj, set_min ? val : min, set_max ? val : max)
: hasp_out_int(obj, attr, set_min ? lv_bar_get_min_value(obj) : lv_bar_get_max_value(obj));
}
if(check_obj_type(objtype, LV_HASP_LMETER)) {
int16_t min = lv_linemeter_get_min_value(obj);
int16_t max = lv_linemeter_get_max_value(obj);
if(update && (set_min ? val : min) >= (set_max ? val : max)) return; // prevent setting min>=max
return update ? lv_linemeter_set_range(obj, set_min ? val : min, set_max ? val : max)
: hasp_out_int(obj, attr,
set_min ? lv_linemeter_get_min_value(obj) : lv_linemeter_get_max_value(obj));
}
}
// OK
// @param update bool: change the value if true, dispatch value if false
/**
* Change or Retrieve the value of the attribute of an object
* @param obj lv_obj_t*: the object to get/set the attribute
* @param attr_p char*: the attribute name (with or without leading ".")
* @param payload char*: the new value of the attribute
* @param update bool: change/set the value if true, dispatch/get value if false
* @note setting a value won't return anything, getting will dispatch the value
*/
void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char * payload, bool update)
{
unsigned long start = millis();
@ -662,11 +763,31 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
case ATTR_Y:
return update ? lv_obj_set_y(obj, val) : hasp_out_int(obj, attr, lv_obj_get_y(obj));
case ATTR_W:
return update ? lv_obj_set_width(obj, val) : hasp_out_int(obj, attr, lv_obj_get_width(obj));
case ATTR_W: {
if(update) {
lv_obj_set_width(obj, val);
if(check_obj_type(obj, LV_HASP_CPICKER)) {
lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC
: LV_CPICKER_TYPE_RECT);
}
} else {
hasp_out_int(obj, attr, lv_obj_get_width(obj));
}
return;
}
case ATTR_H:
return update ? lv_obj_set_height(obj, val) : hasp_out_int(obj, attr, lv_obj_get_height(obj));
case ATTR_H: {
if(update) {
lv_obj_set_height(obj, val);
if(check_obj_type(obj, LV_HASP_CPICKER)) {
lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC
: LV_CPICKER_TYPE_RECT);
}
} else {
hasp_out_int(obj, attr, lv_obj_get_height(obj));
}
return;
}
case ATTR_ID:
return update ? (void)(obj->user_data = (uint8_t)val) : hasp_out_int(obj, attr, obj->user_data);
@ -714,12 +835,12 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
}
break;
case ATTR_RECT:
if(check_obj_type(obj, LV_HASP_CPICKER)) {
lv_cpicker_set_type(obj, is_true(payload) ? LV_CPICKER_TYPE_RECT : LV_CPICKER_TYPE_DISC);
return;
}
break;
// case ATTR_RECT:
// if(check_obj_type(obj, LV_HASP_CPICKER)) {
// lv_cpicker_set_type(obj, is_true(payload) ? LV_CPICKER_TYPE_RECT : LV_CPICKER_TYPE_DISC);
// return;
// }
// break;
case ATTR_MODE:
if(check_obj_type(obj, LV_HASP_BUTTON)) {
@ -789,11 +910,9 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
/* **************************
* Static Inline functions
* **************************/
static inline bool is_true(const char * s)
static bool is_true(const char * s)
{
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")) ||
return (!strcasecmp_P(s, PSTR("true")) || !strcasecmp_P(s, PSTR("on")) || !strcasecmp_P(s, PSTR("yes")) ||
!strcmp_P(s, PSTR("1")));
}
@ -821,6 +940,13 @@ void inline hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color)
hasp_send_obj_attribute_color(obj, attr, color);
}
/**
* Check if an lvgl object typename corresponds to a given HASP object ID
* @param lvobjtype a char* to a string
* @param haspobjtype the HASP object ID to check against
* @return true or false wether the types match
* @note
*/
bool check_obj_type(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype)
{
lvobjtype += 3; // skip "lv_"
@ -842,6 +968,8 @@ bool check_obj_type(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype)
return (strcmp_P(lvobjtype, PSTR("slider")) == 0);
case LV_HASP_GAUGE:
return (strcmp_P(lvobjtype, PSTR("gauge")) == 0);
case LV_HASP_ARC:
return (strcmp_P(lvobjtype, PSTR("arc")) == 0);
case LV_HASP_BAR:
return (strcmp_P(lvobjtype, PSTR("bar")) == 0);
case LV_HASP_LMETER:
@ -869,6 +997,13 @@ bool check_obj_type(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype)
}
}
/**
* Check if an lvgl objecttype name corresponds to a given HASP object ID
* @param obj an lv_obj_t* of the object to check its type
* @param haspobjtype the HASP object ID to check against
* @return true or false wether the types match
* @note
*/
bool check_obj_type(lv_obj_t * obj, lv_hasp_obj_type_t haspobjtype)
{
lv_obj_type_t list;

View File

@ -29,8 +29,8 @@ bool check_obj_type(lv_obj_t * obj, lv_hasp_obj_type_t haspobjtype);
if(update) { \
return lv_obj_set_style_local_##func_name(obj, part, state, (value_type)val); \
} else { \
value_type temp; \
temp = lv_obj_get_style_##func_name(obj, part); \
value_type temp = lv_obj_get_style_##func_name(obj, part); \
/*lv_obj_get_style_##func_name(obj, part, state, &temp);*/ \
return hasp_out_int(obj, attr, temp); \
} \
}
@ -46,7 +46,17 @@ _HASP_ATTRIBUTE(PAD_BOTTOM, pad_bottom, lv_style_int_t)
_HASP_ATTRIBUTE(PAD_LEFT, pad_left, lv_style_int_t)
_HASP_ATTRIBUTE(PAD_RIGHT, pad_right, lv_style_int_t)
_HASP_ATTRIBUTE(PAD_INNER, pad_inner, lv_style_int_t)
#if LV_USE_BLEND_MODES
_HASP_ATTRIBUTE(BG_BLEND_MODE, bg_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(BORDER_BLEND_MODE, border_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(OUTLINE_BLEND_MODE, outline_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(SHADOW_BLEND_MODE, shadow_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(PATTERN_BLEND_MODE, pattern_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(VALUE_BLEND_MODE, value_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(TEXT_BLEND_MODE, text_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(LINE_BLEND_MODE, line_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(IMAGE_BLEND_MODE, image_blend_mode, lv_blend_mode_t)
#endif
_HASP_ATTRIBUTE(BG_MAIN_STOP, bg_main_stop, lv_style_int_t)
_HASP_ATTRIBUTE(BG_GRAD_STOP, bg_grad_stop, lv_style_int_t)
_HASP_ATTRIBUTE(BG_GRAD_DIR, bg_grad_dir, lv_grad_dir_t)
@ -55,31 +65,28 @@ _HASP_ATTRIBUTE(BG_GRAD_DIR, bg_grad_dir, lv_grad_dir_t)
_HASP_ATTRIBUTE(BG_OPA, bg_opa, lv_opa_t)
_HASP_ATTRIBUTE(BORDER_WIDTH, border_width, lv_style_int_t)
_HASP_ATTRIBUTE(BORDER_SIDE, border_side, lv_border_side_t)
_HASP_ATTRIBUTE(BORDER_BLEND_MODE, border_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(BORDER_POST, border_post, bool)
//_HASP_ATTRIBUTE(BORDER_COLOR, border_color, lv_color_t, _color, nonscalar)
_HASP_ATTRIBUTE(BORDER_OPA, border_opa, lv_opa_t)
_HASP_ATTRIBUTE(OUTLINE_WIDTH, outline_width, lv_style_int_t)
_HASP_ATTRIBUTE(OUTLINE_PAD, outline_pad, lv_style_int_t)
_HASP_ATTRIBUTE(OUTLINE_BLEND_MODE, outline_blend_mode, lv_blend_mode_t)
//_HASP_ATTRIBUTE(OUTLINE_COLOR, outline_color, lv_color_t, _color, nonscalar)
_HASP_ATTRIBUTE(OUTLINE_OPA, outline_opa, lv_opa_t)
#if LV_USE_SHADOW
_HASP_ATTRIBUTE(SHADOW_WIDTH, shadow_width, lv_style_int_t)
_HASP_ATTRIBUTE(SHADOW_OFS_X, shadow_ofs_x, lv_style_int_t)
_HASP_ATTRIBUTE(SHADOW_OFS_Y, shadow_ofs_y, lv_style_int_t)
_HASP_ATTRIBUTE(SHADOW_SPREAD, shadow_spread, lv_style_int_t)
_HASP_ATTRIBUTE(SHADOW_BLEND_MODE, shadow_blend_mode, lv_blend_mode_t)
//_HASP_ATTRIBUTE(SHADOW_COLOR, shadow_color, lv_color_t, _color, nonscalar)
_HASP_ATTRIBUTE(SHADOW_OPA, shadow_opa, lv_opa_t)
#endif
_HASP_ATTRIBUTE(PATTERN_REPEAT, pattern_repeat, bool)
_HASP_ATTRIBUTE(PATTERN_BLEND_MODE, pattern_blend_mode, lv_blend_mode_t)
//_HASP_ATTRIBUTE(PATTERN_RECOLOR, pattern_recolor, lv_color_t, _color, nonscalar)
_HASP_ATTRIBUTE(PATTERN_OPA, pattern_opa, lv_opa_t)
_HASP_ATTRIBUTE(PATTERN_RECOLOR_OPA, pattern_recolor_opa, lv_opa_t)
//_HASP_ATTRIBUTE(PATTERN_IMAGE, pattern_image, const void *, _data_ptr, scalar)
_HASP_ATTRIBUTE(VALUE_LETTER_SPACE, value_letter_space, lv_style_int_t)
_HASP_ATTRIBUTE(VALUE_LINE_SPACE, value_line_space, lv_style_int_t)
_HASP_ATTRIBUTE(VALUE_BLEND_MODE, value_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(VALUE_OFS_X, value_ofs_x, lv_style_int_t)
_HASP_ATTRIBUTE(VALUE_OFS_Y, value_ofs_y, lv_style_int_t)
_HASP_ATTRIBUTE(VALUE_ALIGN, value_align, lv_align_t)
@ -90,19 +97,16 @@ _HASP_ATTRIBUTE(VALUE_OPA, value_opa, lv_opa_t)
_HASP_ATTRIBUTE(TEXT_LETTER_SPACE, text_letter_space, lv_style_int_t)
_HASP_ATTRIBUTE(TEXT_LINE_SPACE, text_line_space, lv_style_int_t)
_HASP_ATTRIBUTE(TEXT_DECOR, text_decor, lv_text_decor_t)
_HASP_ATTRIBUTE(TEXT_BLEND_MODE, text_blend_mode, lv_blend_mode_t)
//_HASP_ATTRIBUTE(TEXT_COLOR, text_color, lv_color_t, _color, nonscalar)
//_HASP_ATTRIBUTE(TEXT_SEL_COLOR, text_sel_color, lv_color_t, _color, nonscalar)
_HASP_ATTRIBUTE(TEXT_OPA, text_opa, lv_opa_t)
//_HASP_ATTRIBUTE(TEXT_FONT, text_font, const lv_font_t *, _data_ptr, scalar)
_HASP_ATTRIBUTE(LINE_WIDTH, line_width, lv_style_int_t)
_HASP_ATTRIBUTE(LINE_BLEND_MODE, line_blend_mode, lv_blend_mode_t)
_HASP_ATTRIBUTE(LINE_DASH_WIDTH, line_dash_width, lv_style_int_t)
_HASP_ATTRIBUTE(LINE_DASH_GAP, line_dash_gap, lv_style_int_t)
_HASP_ATTRIBUTE(LINE_ROUNDED, line_rounded, bool)
//_HASP_ATTRIBUTE(LINE_COLOR, line_color, lv_color_t, _color, nonscalar)
_HASP_ATTRIBUTE(LINE_OPA, line_opa, lv_opa_t)
_HASP_ATTRIBUTE(IMAGE_BLEND_MODE, image_blend_mode, lv_blend_mode_t)
//_HASP_ATTRIBUTE(IMAGE_RECOLOR, image_recolor, lv_color_t, _color, nonscalar)
_HASP_ATTRIBUTE(IMAGE_OPA, image_opa, lv_opa_t)
_HASP_ATTRIBUTE(IMAGE_RECOLOR_OPA, image_recolor_opa, lv_opa_t)
@ -123,92 +127,116 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t)
//_HASP_ATTRIBUTE(SCALE_END_COLOR, scale_end_color, lv_color_t, _color, nonscalar)
/* attribute hashes */
/* Object Part Attributes */
#define ATTR_SIZE 16417
#define ATTR_BG_OPA 48966
#define ATTR_RADIUS 20786
#define ATTR_PAD_TOP 59081
#define ATTR_LINE_OPA 24501
#define ATTR_BG_COLOR 64969
#define ATTR_PAD_LEFT 43123
#define ATTR_TEXT_OPA 37166
#define ATTR_IMAGE_OPA 58140
#define ATTR_OPA_SCALE 64875
#define ATTR_PAD_INNER 9930
#define ATTR_PAD_RIGHT 65104
#define ATTR_BORDER_OPA 2061
#define ATTR_VALUE_OPA 50482
#define ATTR_LINE_WIDTH 25467
#define ATTR_LINE_COLOR 22200
#define ATTR_PAD_BOTTOM 3767
#define ATTR_TEXT_FONT 22465
#define ATTR_VALUE_STR 1091
#define ATTR_SHADOW_OPA 38401
#define ATTR_TEXT_COLOR 23473
#define ATTR_TEXT_DECOR 1971
#define ATTR_BORDER_SIDE 53962
#define ATTR_VALUE_FONT 9405
#define ATTR_CLIP_CORNER 9188
#define ATTR_PATTERN_OPA 43633
#define ATTR_OUTLINE_OPA 23011
#define ATTR_BORDER_POST 49491
#define ATTR_OUTLINE_PAD 26038
#define ATTR_SCALE_WIDTH 36017
#define ATTR_OPA_SCALE 64875
#define ATTR_TRANSFORM_HEIGHT 55994
#define ATTR_TRANSFORM_WIDTH 48627
/* Background Attributes */
#define ATTR_BG_OPA 48966
#define ATTR_BG_COLOR 64969
#define ATTR_BG_GRAD_DIR 41782
#define ATTR_VALUE_ALIGN 27895
#define ATTR_VALUE_COLOR 52661
#define ATTR_BG_GRAD_STOP 4025
#define ATTR_VALUE_OFS_X 21415
#define ATTR_VALUE_OFS_Y 21416
#define ATTR_BG_MAIN_STOP 63118
#define ATTR_BORDER_WIDTH 24531
#define ATTR_LINE_ROUNDED 15042
#define ATTR_BORDER_COLOR 21264
#define ATTR_BG_BLEND_MODE 31147
#define ATTR_BG_GRAD_COLOR 44140
#define ATTR_SHADOW_WIDTH 13255
#define ATTR_IMAGE_RECOLOR 52204
#define ATTR_SHADOW_COLOR 9988
#define ATTR_LINE_DASH_GAP 49332
#define ATTR_OUTLINE_WIDTH 9897
#define ATTR_SHADOW_OFS_X 44278
#define ATTR_SHADOW_OFS_Y 44279
#define ATTR_PATTERN_IMAGE 61292
#define ATTR_SHADOW_SPREAD 21138
#define ATTR_OUTLINE_COLOR 6630
/* Padding Attributes */
#define ATTR_PAD_TOP 59081
#define ATTR_PAD_LEFT 43123
#define ATTR_PAD_INNER 9930
#define ATTR_PAD_RIGHT 65104
#define ATTR_PAD_BOTTOM 3767
/* Text Attributes */
#define ATTR_TEXT_OPA 37166
#define ATTR_TEXT_FONT 22465
#define ATTR_TEXT_COLOR 23473
#define ATTR_TEXT_DECOR 1971
#define ATTR_TEXT_LETTER_SPACE 62079
#define ATTR_TEXT_SEL_COLOR 32076
#define ATTR_LINE_DASH_WIDTH 32676
#define ATTR_PATTERN_REPEAT 31338
#define ATTR_LINE_BLEND_MODE 60284
#define ATTR_TEXT_LINE_SPACE 54829
#define ATTR_TEXT_BLEND_MODE 32195
/* Border Attributes */
#define ATTR_BORDER_OPA 2061
#define ATTR_BORDER_SIDE 53962
#define ATTR_BORDER_POST 49491
#define ATTR_BORDER_BLEND_MODE 23844
#define ATTR_BORDER_WIDTH 24531
#define ATTR_BORDER_COLOR 21264
/* Outline Attributes */
#define ATTR_OUTLINE_OPA 23011
#define ATTR_OUTLINE_PAD 26038
#define ATTR_OUTLINE_COLOR 6630
#define ATTR_OUTLINE_BLEND_MODE 25038
#define ATTR_OUTLINE_WIDTH 9897
/* Shadow Attributes */
#define ATTR_SHADOW_OPA 38401
#define ATTR_SHADOW_WIDTH 13255
#define ATTR_SHADOW_OFS_X 44278
#define ATTR_SHADOW_OFS_Y 44279
#define ATTR_SHADOW_SPREAD 21138
#define ATTR_SHADOW_BLEND_MODE 64048
#define ATTR_SHADOW_COLOR 9988
/* Line Attributes */
#define ATTR_LINE_OPA 24501
#define ATTR_LINE_WIDTH 25467
#define ATTR_LINE_COLOR 22200
#define ATTR_LINE_DASH_WIDTH 32676
#define ATTR_LINE_ROUNDED 15042
#define ATTR_LINE_DASH_GAP 49332
#define ATTR_LINE_BLEND_MODE 60284
/* Value Attributes */
#define ATTR_VALUE_OPA 50482
#define ATTR_VALUE_STR 1091
#define ATTR_VALUE_FONT 9405
#define ATTR_VALUE_ALIGN 27895
#define ATTR_VALUE_COLOR 52661
#define ATTR_VALUE_OFS_X 21415
#define ATTR_VALUE_OFS_Y 21416
#define ATTR_VALUE_LINE_SPACE 26921
#define ATTR_VALUE_BLEND_MODE 4287
#define ATTR_VALUE_LETTER_SPACE 51067
/* Pattern attributes */
#define ATTR_PATTERN_BLEND_MODE 43456
#define ATTR_PATTERN_RECOLOR_OPA 35074
#define ATTR_PATTERN_RECOLOR 7745
#define ATTR_PATTERN_REPEAT 31338
#define ATTR_PATTERN_OPA 43633
#define ATTR_PATTERN_IMAGE 61292
#define ATTR_TRANSITION_PROP_1 49343
#define ATTR_TRANSITION_PROP_2 49344
#define ATTR_SCALE_END_COLOR 44074
#define ATTR_TRANSITION_PROP_3 49345
#define ATTR_TRANSFORM_WIDTH 48627
#define ATTR_TRANSITION_PROP_4 49346
#define ATTR_TRANSITION_PROP_5 49347
#define ATTR_TRANSITION_PROP_6 49348
#define ATTR_TRANSITION_TIME 26263
#define ATTR_PATTERN_RECOLOR 7745
#define ATTR_TRANSITION_PATH 43343
#define ATTR_IMAGE_BLEND_MODE 11349
#define ATTR_VALUE_LINE_SPACE 26921
#define ATTR_BORDER_BLEND_MODE 23844
#define ATTR_VALUE_BLEND_MODE 4287
#define ATTR_IMAGE_RECOLOR_OPA 43949
#define ATTR_TRANSITION_DELAY 64537
#define ATTR_SCALE_GRAD_COLOR 47239
#define ATTR_SHADOW_BLEND_MODE 64048
#define ATTR_TRANSFORM_HEIGHT 55994
#define ATTR_TEXT_LETTER_SPACE 62079
#define ATTR_OUTLINE_BLEND_MODE 25038
#define ATTR_PATTERN_BLEND_MODE 43456
#define ATTR_SCALE_BORDER_WIDTH 2440
#define ATTR_VALUE_LETTER_SPACE 51067
#define ATTR_PATTERN_RECOLOR_OPA 35074
#define ATTR_IMAGE_OPA 58140
#define ATTR_IMAGE_RECOLOR 52204
#define ATTR_IMAGE_BLEND_MODE 11349
#define ATTR_IMAGE_RECOLOR_OPA 43949
#define ATTR_SCALE_END_LINE_WIDTH 30324
#define ATTR_SCALE_END_BORDER_WIDTH 34380
#define ATTR_SCALE_BORDER_WIDTH 2440
#define ATTR_SCALE_GRAD_COLOR 47239
#define ATTR_SCALE_WIDTH 36017
#define ATTR_SCALE_END_COLOR 44074
/* Object Attributes */
#define ATTR_X 120
#define ATTR_Y 121
#define ATTR_W 119
@ -220,7 +248,7 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t)
#define ATTR_HIDDEN 11082
#define ATTR_VIS 16320
#define ATTR_MODE 45891
#define ATTR_RECT 11204
// #define ATTR_RECT 11204
#define ATTR_ROWS 52153
#define ATTR_MIN 46130
#define ATTR_MAX 45636

View File

@ -19,6 +19,7 @@
#include "hasp_mqtt.h"
#endif
#include "hasp_conf.h"
#include "hasp_debug.h"
#include "hasp_config.h"
#include "hasp_dispatch.h"
@ -37,6 +38,7 @@
#if HASP_USE_SYSLOG > 0
#include "Syslog.h"
#include <WiFiUdp.h>
#ifndef SYSLOG_SERVER
#define SYSLOG_SERVER ""
@ -71,7 +73,7 @@ Syslog * syslog;
#endif // USE_SYSLOG
// Serial Settings
uint8_t serialInputIndex = 0; // Empty buffer
uint8_t serialInputIndex = 0; // Empty buffer
char serialInputBuffer[1024];
uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10
bool debugSerialStarted = false;
@ -97,7 +99,8 @@ String debugHaspHeader()
String header((char *)0);
header.reserve(256);
if(debugAnsiCodes) header += TERM_COLOR_YELLOW;
header += F(" _____ _____ _____ _____\r\n"
header += F("\r\n"
" _____ _____ _____ _____\r\n"
" | | | _ | __| _ |\r\n"
" | | |__ | __|\r\n"
" |__|__|__|__|_____|__|\r\n"
@ -279,6 +282,9 @@ static void debugPrintLvglMemory(int level, Print * _logOutput)
static void debugPrintPriority(int level, Print * _logOutput)
{
if(_logOutput == &syslogClient) {
}
switch(level) {
case LOG_LEVEL_FATAL:
case LOG_LEVEL_ERROR:
@ -381,23 +387,23 @@ void debugLvgl(lv_log_level_t level, const char * file, uint32_t line, const cha
void debugLoop()
{
while(Serial.available()) {
while(Serial.available()) {
char ch = Serial.read();
Serial.print(ch);
if(ch == 13 || ch == 10) {
serialInputBuffer[serialInputIndex] = 0;
if(serialInputIndex > 0) dispatchCommand(serialInputBuffer);
if(serialInputIndex > 0) dispatchTextLine(serialInputBuffer);
serialInputIndex = 0;
} else {
if(serialInputIndex < sizeof(serialInputBuffer) - 1) {
serialInputBuffer[serialInputIndex++] = ch;
}
serialInputBuffer[serialInputIndex] = 0;
if(strcmp(serialInputBuffer, "jsonl=") == 0) {
dispatchJsonl(Serial);
serialInputIndex = 0;
}
// if(strcmp(serialInputBuffer, "jsonl=") == 0) {
// dispatchJsonl(Serial);
// serialInputIndex = 0;
// }
}
serialInputBuffer[serialInputIndex] = 0;
}
}
@ -442,7 +448,7 @@ void debugLoop()
void debugEverySecond()
{
if(debugTelePeriod > 0 && (millis() - debugLastMillis) >= debugTelePeriod * 1000) {
dispatchStatusUpdate();
dispatch_output_statusupdate();
debugLastMillis = millis();
}
// printLocalTime();

View File

@ -8,27 +8,15 @@
#include "hasp_debug.h"
#include "hasp_gpio.h"
#include "hasp_gui.h"
#include "hasp_oobe.h"
#include "hasp_hal.h"
#include "hasp.h"
#include "hasp_conf.h"
inline void dispatchPrintln(String header, String & data)
inline bool isON(const char * payload)
{
Log.notice(F("%s: %s"), header.c_str(), data.c_str());
}
bool isON(const char * payload)
{
return strcmp_P(payload, PSTR("ON")) == 0;
}
String getOnOff(bool state)
{
String result((char *)0);
result.reserve(128);
result = state ? F("ON") : F("OFF");
return result;
return strcasecmp_P(payload, PSTR("ON")) == 0;
}
void dispatchSetup()
@ -37,14 +25,31 @@ void dispatchSetup()
void dispatchLoop()
{}
void dispatchStatusUpdate()
// Send status update message to the client
void dispatch_output_statusupdate()
{
#if HASP_USE_MQTT > 0
mqtt_send_statusupdate();
#endif
}
void dispatchOutput(int output, bool state)
// Format filesystem and erase EEPROM
bool dispatch_factory_reset()
{
bool formated, erased = true;
#if HASP_USE_SPIFFS > 0
formated = SPIFFS.format();
#endif
#if HASP_USE_EEPROM > 0
erased = false;
#endif
return formated && erased;
}
void dispatchGpioOutput(int output, bool state)
{
int pin = 0;
@ -62,16 +67,63 @@ void dispatchOutput(int output, bool state)
}
}
void dispatchOutput(String strTopic, const char * payload)
void dispatchGpioOutput(String strTopic, const char * payload)
{
String strTemp((char *)0);
strTemp.reserve(128);
strTemp = strTopic.substring(7, strTopic.length());
dispatchOutput(strTemp.toInt(), isON(payload));
dispatchGpioOutput(strTemp.toInt(), isON(payload));
}
void dispatchButtonAttribute(String & strTopic, const char * payload)
void dispatchParseJson(char * payload)
{ // Parse an incoming JSON array into individual commands
/* if(strPayload.endsWith(",]")) {
// Trailing null array elements are an artifact of older Home Assistant automations
// and need to be removed before parsing by ArduinoJSON 6+
strPayload.remove(strPayload.length() - 2, 2);
strPayload.concat("]");
}*/
size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 256;
DynamicJsonDocument haspCommands(maxsize);
DeserializationError jsonError = deserializeJson(haspCommands, payload);
// haspCommands.shrinkToFit();
if(jsonError) { // Couldn't parse incoming JSON command
Log.warning(F("JSON: Failed to parse incoming JSON command with error: %s"), jsonError.c_str());
} else {
JsonArray arr = haspCommands.as<JsonArray>();
for(JsonVariant command : arr) {
dispatchTextLine(command.as<String>().c_str());
}
}
}
void dispatchParseJsonl(Stream & stream)
{
DynamicJsonDocument jsonl(3 * 128u);
uint8_t savedPage = haspGetPage();
// Log.notice(F("DISPATCH: jsonl"));
while(deserializeJson(jsonl, stream) == DeserializationError::Ok) {
// serializeJson(jsonl, Serial);
// Serial.println();
haspNewObject(jsonl.as<JsonObject>(), savedPage);
}
}
void dispatchParseJsonl(char * payload)
{
CharStream stream(payload);
dispatchParseJsonl(stream);
}
// p[x].b[y]=value
inline void dispatch_process_button_attribute(String strTopic, const char * payload)
{
// Log.trace(F("BTN ATTR: %s = %s"), strTopic.c_str(), payload);
String strPageId((char *)0);
String strTemp((char *)0);
@ -96,201 +148,246 @@ void dispatchButtonAttribute(String & strTopic, const char * payload)
}
// objectattribute=value
void dispatchAttribute(String strTopic, const char * payload)
void dispatchCommand(const char * topic, const char * payload)
{
if(strTopic.startsWith("p[")) {
dispatchButtonAttribute(strTopic, payload);
if(!strcmp_P(topic, PSTR("json"))) { // '[...]/device/command/json' -m '["dim=5", "page 1"]' =
// nextionSendCmd("dim=50"), nextionSendCmd("page 1")
dispatchParseJson((char *)payload);
} else if(strTopic == F("page")) {
} else if(!strcmp_P(topic, PSTR("jsonl"))) {
dispatchParseJsonl((char *)payload);
} else if(!strcmp_P(topic, PSTR("page"))) {
dispatchPage(payload);
} else if(strTopic == F("dim") || strTopic == F("brightness")) {
} else if(!strcmp_P(topic, PSTR("dim")) || !strcmp_P(topic, PSTR("brightness"))) {
dispatchDim(payload);
} else if(strTopic == F("light")) {
} else if(!strcmp_P(topic, PSTR("light"))) {
dispatchBacklight(payload);
} else if(strTopic == F("reboot") || strTopic == F("restart")) {
} else if(!strcmp_P(topic, PSTR("reboot")) || !strcmp_P(topic, PSTR("restart"))) {
dispatchReboot(true);
} else if(strTopic == F("clearpage")) {
} else if(!strcmp_P(topic, PSTR("factoryreset"))) {
dispatch_factory_reset();
delay(250);
dispatchReboot(false); // don't save config
} else if(!strcmp_P(topic, PSTR("clearpage"))) {
dispatchClearPage(payload);
} else if(strTopic == F("update")) {
} else if(!strcmp_P(topic, PSTR("update"))) {
dispatchWebUpdate(payload);
} else if(strTopic == F("clearconfig")) {
configClear();
} else if(!strcmp_P(topic, PSTR("setupap"))) {
oobeFakeSetup();
} else if(strTopic == F("setupap")) {
// haspDisplayAP(String(F("HASP-ABC123")).c_str(), String(F("haspadmin")).c_str());
} else if(strlen(topic) == 7 && topic == strstr_P(topic, PSTR("output"))) {
dispatchGpioOutput(topic, payload);
} else if(strTopic.length() == 7 && strTopic.startsWith(F("output"))) {
dispatchOutput(strTopic, payload);
}
}
} else if(strcasecmp_P(topic, PSTR("calibrate")) == 0) {
guiCalibrate();
void dispatchPage(String strPageid)
{
dispatchPrintln(F("PAGE"), strPageid);
} else if(strcasecmp_P(topic, PSTR("wakeup")) == 0) {
haspWakeUp();
} else if(strcasecmp_P(topic, PSTR("screenshot")) == 0) {
guiTakeScreenshot("/screenhot.bmp");
} else if(strcasecmp_P(topic, PSTR("")) == 0 || strcasecmp_P(topic, PSTR("statusupdate")) == 0) {
dispatch_output_statusupdate();
} else if(topic == strstr_P(topic, PSTR("p["))) {
dispatch_process_button_attribute(topic, payload);
} else if(!strcmp_P(topic, F_CONFIG_SSID) || !strcmp_P(topic, F_CONFIG_PASS)) {
DynamicJsonDocument settings(45);
settings[topic] = payload;
wifiSetConfig(settings.as<JsonObject>());
} else if(!strcmp_P(topic, PSTR("mqtthost")) || !strcmp_P(topic, PSTR("mqttport")) ||
!strcmp_P(topic, PSTR("mqttuser")) || !strcmp_P(topic, PSTR("mqttpass"))) {
char item[5];
memset(item, 0, sizeof(item));
strncpy(item, topic + 4, 4);
DynamicJsonDocument settings(45);
settings[item] = payload;
mqttSetConfig(settings.as<JsonObject>());
if(strPageid.length() == 0) {
} else {
if(strPageid.toInt() <= 250) haspSetPage(strPageid.toInt());
if(strlen(payload) == 0) {
// dispatchTextLine(topic); // Could cause an infinite loop!
}
Log.warning(F(LOG_CMND_CTR "Command not found %s => %s"), topic, payload);
}
String strPage((char *)0);
strPage.reserve(128);
strPage = haspGetPage();
}
// Get or Set a page
void dispatchPage(const char * page)
{
// dispatchPrintln(F("PAGE"), strPageid);
if(strlen(page) > 0 && atoi(page) <= 250) {
haspSetPage(atoi(page));
}
// Log result
char buffer[4];
itoa(haspGetPage(), buffer, DEC);
#if HASP_USE_MQTT > 0
mqtt_send_state(F("page"), strPage.c_str());
mqtt_send_state(F("page"), buffer);
#endif
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_state(F("page"), strPage.c_str());
slave_send_state(F("page"), buffer);
#endif
}
void dispatchClearPage(String strPageid)
// Clears a page id or the current page if empty
void dispatchClearPage(const char * page)
{
dispatchPrintln(F("CLEAR"), strPageid);
if(strPageid.length() == 0) {
if(strlen(page) == 0) {
haspClearPage(haspGetPage());
} else {
haspClearPage(strPageid.toInt());
haspClearPage(atoi(page));
}
}
void dispatchDim(String strDimLevel)
void dispatchDim(const char * level)
{
// Set the current state
if(strDimLevel.length() != 0) guiSetDim(strDimLevel.toInt());
dispatchPrintln(F("DIM"), strDimLevel);
char buffer[8];
if(strlen(level) != 0) guiSetDim(atoi(level));
// dispatchPrintln(F("DIM"), strDimLevel);
char buffer[4];
#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)
void dispatchBacklight(const char * payload)
{
strPayload.toUpperCase();
dispatchPrintln(F("LIGHT"), strPayload);
// strPayload.toUpperCase();
// dispatchPrintln(F("LIGHT"), strPayload);
// Set the current state
if(strPayload.length() != 0) guiSetBacklight(isON(strPayload.c_str()));
if(strlen(payload) != 0) guiSetBacklight(isON(payload));
// Return the current state
strPayload = getOnOff(guiGetBacklight());
// Return the current state
#if HASP_USE_MQTT > 0
mqtt_send_state(F("light"), strPayload.c_str());
mqtt_send_state(F("light"), guiGetBacklight() ? PSTR("ON") : PSTR("OFF"));
#endif
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_state(F("light"), strPayload.c_str());
slave_send_state(F("light"), guiGetBacklight() ? PSTR("ON") : PSTR("OFF"));
#endif
}
void dispatchCommand(String cmnd)
// Strip command/config prefix from the topic and process the payload
void dispatchTopicPayload(const char * topic, const char * payload)
{
dispatchPrintln(F("CMND"), cmnd);
// Log.trace(F("TOPIC: short topic: %s"), topic);
if(!strcmp_P(topic, PSTR("command"))) {
dispatchTextLine((char *)payload);
return;
}
if(topic == strstr_P(topic, PSTR("command/"))) { // startsWith command/
topic += 8u;
// Log.trace(F("MQTT IN: command subtopic: %s"), topic);
// '[...]/device/command/p[1].b[4].txt' -m '"Lights On"' ==
// nextionSetAttr("p[1].b[4].txt", "\"Lights On\"")
dispatchCommand(topic, (char *)payload);
return;
}
if(topic == strstr_P(topic, PSTR("config/"))) { // startsWith command/
topic += 7u;
dispatchConfig(topic, (char *)payload);
return;
}
dispatchCommand(topic, (char *)payload); // dispatch as is
}
// Parse one line of text and execute the command(s)
void dispatchTextLine(const char * cmnd)
{
// dispatchPrintln(F("CMND"), cmnd);
if(cmnd == strstr_P(cmnd, PSTR("page "))) { // startsWith command/
dispatchPage(cmnd + 5);
if(cmnd.startsWith(F("page "))) {
cmnd = cmnd.substring(5, cmnd.length());
String strTopic((char *)0);
strTopic.reserve(128);
strTopic = F("page");
dispatchAttribute(strTopic, cmnd.c_str());
} else if(cmnd == F("calibrate")) {
guiCalibrate();
} else if(cmnd == F("wakeup")) {
haspWakeUp();
} else if(cmnd == F("screenshot")) {
// guiTakeScreenshot("/screenhot.bmp");
} else if(cmnd == F("") || cmnd == F("statusupdate")) {
dispatchStatusUpdate();
} else {
size_t pos1 = std::string(cmnd).find("=");
size_t pos2 = std::string(cmnd).find(" ");
int pos = 0;
if(pos1 != std::string::npos) {
if(pos2 != std::string::npos) {
pos = (pos1 < pos2 ? pos1 : pos2);
} else {
pos = pos1;
}
} else if(pos2 != std::string::npos) {
pos = pos2;
} else {
pos = 0;
}
int pos = cmnd.indexOf("=");
if(pos > 0) {
String strTopic((char *)0);
String strPayload((char *)0);
// String strPayload((char *)0);
strTopic.reserve(128);
strPayload.reserve(128);
strTopic.reserve(pos + 1);
// strPayload.reserve(128);
strTopic = cmnd.substring(0, pos);
strPayload = cmnd.substring(pos + 1, cmnd.length());
strTopic = String(cmnd).substring(0, pos);
// strPayload = cmnd.substring(pos + 1, cmnd.length());
// cmnd[pos] = 0; // change '=' character into '\0'
dispatchAttribute(strTopic, strPayload.c_str());
dispatchTopicPayload(strTopic.c_str(),
cmnd + pos + 1); // topic is before '=', payload is after '=' position
} else {
dispatchAttribute(cmnd, "");
dispatchTopicPayload(cmnd, "");
}
}
}
void dispatchJson(char * payload)
{ // Parse an incoming JSON array into individual commands
/* if(strPayload.endsWith(",]")) {
// Trailing null array elements are an artifact of older Home Assistant automations
// and need to be removed before parsing by ArduinoJSON 6+
strPayload.remove(strPayload.length() - 2, 2);
strPayload.concat("]");
}*/
size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 256;
DynamicJsonDocument haspCommands(maxsize);
DeserializationError jsonError = deserializeJson(haspCommands, payload);
// haspCommands.shrinkToFit();
if(jsonError) { // Couldn't parse incoming JSON command
Log.warning(F("JSON: Failed to parse incoming JSON command with error: %s"), jsonError.c_str());
} else {
JsonArray arr = haspCommands.as<JsonArray>();
for(JsonVariant command : arr) {
dispatchCommand(command.as<String>());
}
}
}
void dispatchJsonl(Stream & stream)
{
DynamicJsonDocument jsonl(3 * 128u);
uint8_t savedPage = haspGetPage();
Log.notice(F("DISPATCH: jsonl"));
while(deserializeJson(jsonl, stream) == DeserializationError::Ok) {
// serializeJson(jsonl, Serial);
// Serial.println();
haspNewObject(jsonl.as<JsonObject>(), savedPage);
}
}
void dispatchJsonl(char * payload)
{
CharStream stream(payload);
dispatchJsonl(stream);
}
void dispatchIdle(const char * state)
// send idle state to the client
void dispatch_output_idle_state(const char * state)
{
#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
}
// restart the device
void dispatchReboot(bool saveConfig)
{
if(saveConfig) configWriteConfig();
@ -394,6 +491,20 @@ void dispatch_send_group_event(uint8_t groupid, uint8_t eventid, bool update_has
if(update_hasp) hasp_set_group_objects(groupid, eventid, NULL);
}
void IRAM_ATTR dispatch_send_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);
#endif
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_obj_attribute_str(pageid, btnid, attribute, data);
#endif
#endif
}
void dispatch_send_object_event(uint8_t pageid, uint8_t objid, uint8_t eventid)
{
if(objid < 100) {
@ -414,7 +525,8 @@ void dispatchWebUpdate(const char * espOtaUrl)
#endif
}
void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
// send return output back to the client
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);
@ -428,6 +540,7 @@ void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, co
#endif
}
// Get or Set a part of the config.json file
void dispatchConfig(const char * topic, const char * payload)
{
DynamicJsonDocument doc(128 * 2);
@ -450,21 +563,21 @@ void dispatchConfig(const char * topic, const char * payload)
update = true;
}
if(strcmp_P(topic, PSTR("debug")) == 0) {
if(strcasecmp_P(topic, PSTR("debug")) == 0) {
if(update)
debugSetConfig(settings);
else
debugGetConfig(settings);
}
else if(strcmp_P(topic, PSTR("gui")) == 0) {
else if(strcasecmp_P(topic, PSTR("gui")) == 0) {
if(update)
guiSetConfig(settings);
else
guiGetConfig(settings);
}
else if(strcmp_P(topic, PSTR("hasp")) == 0) {
else if(strcasecmp_P(topic, PSTR("hasp")) == 0) {
if(update)
haspSetConfig(settings);
else
@ -472,14 +585,14 @@ void dispatchConfig(const char * topic, const char * payload)
}
#if HASP_USE_WIFI > 0
else if(strcmp_P(topic, PSTR("wifi")) == 0) {
else if(strcasecmp_P(topic, PSTR("wifi")) == 0) {
if(update)
wifiSetConfig(settings);
else
wifiGetConfig(settings);
}
#if HASP_USE_MQTT > 0
else if(strcmp_P(topic, PSTR("mqtt")) == 0) {
else if(strcasecmp_P(topic, PSTR("mqtt")) == 0) {
if(update)
mqttSetConfig(settings);
else
@ -487,11 +600,11 @@ void dispatchConfig(const char * topic, const char * payload)
}
#endif
#if HASP_USE_TELNET > 0
// else if(strcmp_P(topic, PSTR("telnet")) == 0)
// else if(strcasecmp_P(topic, PSTR("telnet")) == 0)
// telnetGetConfig(settings[F("telnet")]);
#endif
#if HASP_USE_MDNS > 0
else if(strcmp_P(topic, PSTR("mdns")) == 0) {
else if(strcasecmp_P(topic, PSTR("mdns")) == 0) {
if(update)
mdnsSetConfig(settings);
else
@ -499,7 +612,7 @@ void dispatchConfig(const char * topic, const char * payload)
}
#endif
#if HASP_USE_HTTP > 0
else if(strcmp_P(topic, PSTR("http")) == 0) {
else if(strcasecmp_P(topic, PSTR("http")) == 0) {
if(update)
httpSetConfig(settings);
else

View File

@ -3,26 +3,29 @@
#include "ArduinoJson.h"
#define LOG_CMND_CTR "CMND: "
void dispatchSetup(void);
void dispatchLoop(void);
void dispatchAttribute(String strTopic, const char * strPayload);
void dispatchCommand(String cmnd);
// void dispatchCommand(const char * topic, const char * payload); // intenal
void dispatchConfig(const char * topic, const char * payload);
void dispatchTopicPayload(const char * topic, const char * payload);
void dispatchTextLine(const char * cmnd);
void dispatchJson(char * strPayload);
void dispatchJsonl(char * strPayload);
void dispatchJsonl(Stream & stream);
// void dispatchParseJson(char * strPayload);
// void dispatchParseJsonl(char * strPayload);
void dispatchParseJsonl(Stream & stream);
void dispatchPage(String strPageid);
void dispatchClearPage(String strPageid);
void dispatchDim(String strDimLevel);
void dispatchBacklight(String strPayload);
void dispatchPage(const char * page);
void dispatchClearPage(const char * page);
void dispatchDim(const char * level);
void dispatchBacklight(const char * payload);
void dispatchWebUpdate(const char * espOtaUrl);
void dispatchIdle(const char * state);
void dispatch_output_idle_state(const char * state);
void dispatchReboot(bool saveConfig);
void dispatchStatusUpdate(void);
void dispatch_output_statusupdate(void);
void dispatch_button(uint8_t id, const char * event);

View File

@ -4,7 +4,7 @@
#include "hasp_conf.h"
#include "hasp_hal.h"
#if HASP_USE_ETHERNET > 0
#if HASP_USE_ETHERNET > 0 && !defined(ARDUINO_ARCH_ESP32)
EthernetClient EthClient;
IPAddress ip;

View File

@ -0,0 +1,64 @@
#include <Arduino.h>
#include "ArduinoJson.h"
#include "ArduinoLog.h"
#include "hasp_conf.h"
#include "hasp_hal.h"
#if HASP_USE_ETHERNET > 0
IPAddress ip;
void EthernetEvent(WiFiEvent_t event)
{
switch (event) {
case SYSTEM_EVENT_ETH_START:
Log.notice(F(LOG_ETH_CTR "Started"));
//set eth hostname here
ETH.setHostname("esp32-ethernet");
break;
case SYSTEM_EVENT_ETH_CONNECTED:
Log.notice(F(LOG_ETH_CTR "Connected"));
break;
case SYSTEM_EVENT_ETH_GOT_IP:
Log.notice(F(LOG_ETH_CTR "MAC Address %s"), ETH.macAddress().c_str());
ip = ETH.localIP();
Log.notice(F(LOG_ETH_CTR "IPv4: %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
if (ETH.fullDuplex()) {
Log.notice(F(LOG_ETH_CTR "FULL_DUPLEX"));
}
Log.notice(F(LOG_ETH_CTR "LINK_SPEED %d Mbps"), ETH.linkSpeed());
eth_connected = true;
break;
case SYSTEM_EVENT_ETH_DISCONNECTED:
Log.notice(F(LOG_ETH_CTR "Disconnected"));
eth_connected = false;
break;
case SYSTEM_EVENT_ETH_STOP:
Log.notice(F(LOG_ETH_CTR "Stopped"));
eth_connected = false;
break;
default:
break;
}
}
void ethernetSetup()
{
WiFi.onEvent(EthernetEvent);
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLKMODE);
}
void ethernetLoop(void)
{
//
}
bool ethernetEvery5Seconds()
{
Log.warning(F(LOG_ETH_CTR "%s"), eth_connected ? F("ONLINE") : F("OFFLINE"));
return eth_connected;
}
#endif

13
src/hasp_ethernet_esp32.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef HASP_ETHERNET_ESP32_H
#define HASP_ETHERNET_ESP32_H
#define LOG_ETH_CTR "ETH: "
static bool eth_connected = false;
void ethernetSetup();
void ethernetLoop(void);
bool ethernetEvery5Seconds();
#endif

View File

@ -15,7 +15,13 @@ uint8_t gpioUsedInputCount = 0;
using namespace ace_button;
static AceButton * button[HASP_NUM_INPUTS];
hasp_gpio_config_t gpioConfig[HASP_NUM_GPIO_CONFIG];
// An array of button pins, led pins, and the led states. Cannot be const
// because ledState is mutable.
hasp_gpio_config_t gpioConfig[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 {
@ -176,19 +182,13 @@ void gpioSetup()
// return;
#if defined(ARDUINO_ARCH_ESP8266)
gpioConfig[0] = {D2, 7, HASP_GPIO_BUTTON, INPUT_PULLUP};
gpioConfig[1] = {D1, 7, HASP_GPIO_LED, OUTPUT};
// gpioAddButton(D2, INPUT_PULLUP, HIGH, 1);
// pinMode(D1, OUTPUT);
gpioAddButton(D2, INPUT_PULLUP, HIGH, 1);
pinMode(D1, OUTPUT);
#endif
#if defined(ARDUINO_ARCH_ESP32)
gpioConfig[0] = {D2, 0, HASP_GPIO_SWITCH, INPUT};
gpioConfig[1] = {D1, 1, HASP_GPIO_RELAY, OUTPUT};
// gpioAddButton(D2, INPUT, HIGH, 1);
// pinMode(D1, OUTPUT);
// gpioAddButton( D2, INPUT, HIGH, 1);
// pinMode(D1, OUTPUT);
#endif
/*

View File

@ -85,19 +85,19 @@ static bool guiCheckSleep()
uint32_t idle = lv_disp_get_inactive_time(NULL);
if(idle >= (guiSleepTime1 + guiSleepTime2) * 1000U) {
if(guiSleeping != 2) {
dispatchIdle(("LONG")); // Literal string
dispatch_output_idle_state(("LONG")); // Literal string
guiSleeping = 2;
}
return true;
} else if(idle >= guiSleepTime1 * 1000U) {
if(guiSleeping != 1) {
dispatchIdle(("SHORT")); // Literal string
dispatch_output_idle_state(("SHORT")); // Literal string
guiSleeping = 1;
}
return true;
}
if(guiSleeping != 0) {
dispatchIdle(("OFF")); // Literal string
dispatch_output_idle_state(("OFF")); // Literal string
guiSleeping = 0;
}
return false;
@ -513,9 +513,9 @@ void guiSetup()
/* Dump TFT Configuration */
// tftSetup(tft);
#ifdef USE_DMA_TO_TFT
Log.verbose(F("TFT: DMA : ENABELD"));
Log.verbose(F("TFT: DMA : ENABLED"));
#else
Log.verbose(F("TFT: DMA : DISABELD"));
Log.verbose(F("TFT: DMA : DISABLED"));
#endif
/* Load User Settings */

View File

@ -127,6 +127,10 @@ String halGetChipModel()
String model((char *)0);
model.reserve(128);
#if defined(STM32F4xx)
model = F("STM32");
#endif
#if defined(STM32F4xx)
model = F("STM32F4xx");
@ -149,7 +153,7 @@ String halGetChipModel()
break;
#endif
default:
model = F("Unknown ESP");
model = F("Unknown ESP32");
}
model += F(" rev");
model += chip_info.revision;

View File

@ -382,10 +382,14 @@ void webHandleAbout()
F("<p><h3>ArduinoLog</h3>Copyright&copy; 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, "
"dhylands, Josha blemasle, mfalkvidd");
httpMessage += FPSTR(MIT_LICENSE);
#if HASP_USE_SYSLOG > 0
httpMessage += F("<p><h3>Syslog</h3>Copyright&copy; 2016 Martin Sloup");
httpMessage += FPSTR(MIT_LICENSE);
#endif
#if HASP_USE_QRCODE > 0
httpMessage += F("<p><h3>QR Code generator</h3>Copyright&copy; Project Nayuki");
httpMessage += FPSTR(MIT_LICENSE);
#endif
httpMessage += F("<p><h3>AceButton</h3>Copyright&copy; 2018 Brian T. Park");
httpMessage += FPSTR(MIT_LICENSE);
@ -1094,7 +1098,7 @@ void webHandleGuiConfig()
}
webSendFooter();
if(webServer.hasArg(F("action"))) dispatchCommand(webServer.arg(F("action")));
if(webServer.hasArg(F("action"))) dispatchTextLine(webServer.arg(F("action")).c_str());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1390,6 +1394,7 @@ void webHandleDebugConfig()
httpMessage += settings[FPSTR(F_DEBUG_TELEPERIOD)].as<String>();
httpMessage += F("'></p>");
#if HASP_USE_SYSLOG > 0
httpMessage += F("<b>Syslog Hostame</b> <i><small>(optional)</small></i><input id='host' "
"name='host' maxlength=31 placeholder='logserver' value='");
httpMessage += settings[FPSTR(F_CONFIG_HOST)].as<String>();
@ -1408,6 +1413,7 @@ void webHandleDebugConfig()
httpMessage += F(">IETF (RFC 5424) &nbsp; <input id='proto' name='proto' type='radio' value='1'");
if(settings[FPSTR(F_CONFIG_PROTOCOL)].as<uint8_t>() == 1) httpMessage += F(" checked");
httpMessage += F(">BSD (RFC 3164)");
#endif
httpMessage += F("</p><p><button type='submit' name='save' value='debug'>Save Settings</button></p></form>");
@ -1459,10 +1465,11 @@ void webHandleHaspConfig()
httpMessage += getOption(3, F("Mono"), themeid == 3);
#endif
#if LV_USE_THEME_MATERIAL == 1
httpMessage += getOption(4, F("Material"), themeid == 4);
httpMessage += getOption(4, F("Material Light"), themeid == 4);
httpMessage += getOption(9, F("Material Dark"), themeid == 9);
#endif
#if LV_USE_THEME_ZEN == 1
httpMessage += getOption(5, F("Zen"), themeid == 5);
// httpMessage += getOption(5, F("Zen"), themeid == 5);
#endif
#if LV_USE_THEME_NEMO == 1
httpMessage += getOption(6, F("Nemo"), themeid == 6);
@ -1636,7 +1643,7 @@ void httpHandleResetConfig()
if(resetConfirmed) { // User has confirmed, so reset everything
bool formatted = configClear();
if(formatted) {
httpMessage += F("<b>Resetting all saved settings and restarting device into WiFi AP mode</b>");
httpMessage += F("<b>Resetting all saved settings and restarting device</b>");
} else {
httpMessage += F("<b>Failed to format the internal flash partition</b>");
resetConfirmed = false;
@ -1684,7 +1691,11 @@ void webStart()
#endif
#else
IPAddress ip;
#if defined(ARDUINO_ARCH_ESP32)
ip = ETH.localIP();
#else
ip = Ethernet.localIP();
#endif
Log.notice(F("HTTP: Server started @ http://%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
#endif
}

View File

@ -251,9 +251,12 @@ void mqtt_send_statusupdate()
////////////////////////////////////////////////////////////////////////////////////////////////////
// Receive incoming messages
static void mqtt_message_cb(char * topic_p, byte * payload, unsigned int length)
{ // Handle incoming commands from MQTT
if(length >= MQTT_MAX_PACKET_SIZE) return; // Check if payload fits the buffer
payload[length] = '\0'; // There's room in the buffer
{ // Handle incoming commands from MQTT
if(length >= MQTT_MAX_PACKET_SIZE) {
Log.error(F("MQTT RCV: Payload too long (%d bytes)"), length);
return;
}
payload[length] = '\0';
// String strTopic((char *)0);
// strTopic.reserve(MQTT_MAX_PACKET_SIZE);
@ -284,44 +287,16 @@ static void mqtt_message_cb(char * topic_p, byte * payload, unsigned int length)
Log.error(F("MQTT: Message received with invalid topic"));
return;
}
// Log.trace(F("MQTT IN: short topic: %s"), topic);
if(!strcmp_P(topic, PSTR("command"))) {
dispatchCommand((char *)payload);
return;
}
if(topic == strstr_P(topic, PSTR("command/"))) { // startsWith command/
topic += 8u;
// Log.trace(F("MQTT IN: command subtopic: %s"), topic);
if(!strcmp_P(topic, PSTR("json"))) { // '[...]/device/command/json' -m '["dim=5", "page 1"]' =
// nextionSendCmd("dim=50"), nextionSendCmd("page 1")
dispatchJson((char *)payload); // Send to nextionParseJson()
} else if(!strcmp_P(topic, PSTR("jsonl"))) {
dispatchJsonl((char *)payload);
} else if(length == 0) {
dispatchCommand(topic);
} else { // '[...]/device/command/p[1].b[4].txt' -m '"Lights On"' ==
// nextionSetAttr("p[1].b[4].txt", "\"Lights On\"")
dispatchAttribute(topic, (char *)payload);
}
return;
}
if(topic == strstr_P(topic, PSTR("config/"))) { // startsWith command/
topic += 7u;
dispatchConfig(topic, (char *)payload);
return;
}
// catch a dangling LWT from a previous connection if it appears
if(!strcmp_P(topic, PSTR("status")) && !strcmp_P((char *)payload, PSTR("OFF"))) {
if(!strcmp_P(topic, PSTR("status")) && !strcasecmp_P((char *)payload, PSTR("OFF"))) {
char topicBuffer[128];
snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic);
mqttClient.publish(topicBuffer, "ON", true);
Log.notice(F("MQTT: binary_sensor state: [status] : ON"));
return;
// return;
} else {
dispatchTopicPayload(topic, (char *)payload);
}
/*
@ -471,7 +446,9 @@ void mqttReconnect()
mqttReconnectCount = 0;
haspReconnect();
dispatchPage(String(haspGetPage()));
char page[4] = "999";
itoa(haspGetPage(), page, DEC);
dispatchPage(page);
mqtt_send_statusupdate();
}
@ -492,9 +469,9 @@ void mqttLoop()
if(mqttEnabled) mqttClient.loop();
}
void mqttEvery5Seconds(bool wifiIsConnected)
void mqttEvery5Seconds(bool networkIsConnected)
{
if(mqttEnabled && wifiIsConnected && !mqttClient.connected()) mqttReconnect();
if(mqttEnabled && networkIsConnected && !mqttClient.connected()) mqttReconnect();
}
String mqttGetNodename()

View File

@ -14,6 +14,10 @@
#include "hasp_config.h"
#include "hasp_dispatch.h"
static bool oobeAutoCalibrate = true;
#if HASP_USE_WIFI > 0
#if HASP_USE_QRCODE > 0
#include "lv_qrcode.h"
#endif
@ -21,18 +25,13 @@
static lv_obj_t * oobepage[2];
static lv_obj_t * oobekb;
extern lv_font_t * defaultFont;
static bool oobeAutoCalibrate = true;
lv_obj_t * pwd_ta;
void oobeSetAutoCalibrate(bool cal)
{
oobeAutoCalibrate = cal;
}
static inline void oobeSetPage(uint8_t pageid)
{
lv_scr_load(oobepage[pageid]);
lv_obj_invalidate(lv_disp_get_layer_sys(NULL));
}
void gotoPage1_cb(lv_obj_t * event_kb, lv_event_t event)
@ -292,28 +291,64 @@ static void oobe_calibrate_cb(lv_obj_t * ta, lv_event_t event)
}
}
}
#endif // HASP_USE_WIFI
void oobeSetup()
void oobeSetAutoCalibrate(bool cal)
{
oobeAutoCalibrate = cal;
}
bool oobeSetup()
{
#if HASP_USE_ETHERNET > 0
if(eth_connected) return false;
#endif
#if HASP_USE_WIFI > 0
char ssid[32];
char pass[32];
#if HASP_USE_WIFI>0
if(wifiShowAP(ssid, pass)) {
guiSetDim(100);
oobeSetupQR(ssid, pass);
oobeSetupSsid();
oobeSetPage(0);
lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), gotoPage1_cb);
if(oobeAutoCalibrate) {
lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), oobe_calibrate_cb);
Log.verbose(F("OOBE: Enabled Auto Calibrate on touch"));
} else {
lv_obj_set_click(lv_disp_get_layer_sys(NULL), false);
lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), gotoPage1_cb);
Log.verbose(F("OOBE: Already calibrated"));
}
oobeSetPage(0);
return true;
} else {
return false;
}
#endif
return false;
}
void oobeFakeSetup()
{
#if HASP_USE_WIFI > 0
char ssid[32] = "HASP-ABCDEF";
char pass[32] = "haspadmin";
guiSetDim(100);
oobeSetupQR(ssid, pass);
oobeSetupSsid();
oobeSetPage(0);
lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), gotoPage1_cb);
if(oobeAutoCalibrate) {
lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), oobe_calibrate_cb);
Log.verbose(F("OOBE: Enabled Auto Calibrate on touch"));
} else {
Log.verbose(F("OOBE: Already calibrated"));
}
#endif
}

View File

@ -1,2 +1,3 @@
void oobeSetAutoCalibrate(bool cal);
void oobeSetup();
bool oobeSetup();
void oobeFakeSetup();

View File

@ -35,7 +35,8 @@ static WiFiClient otaClient;
std::string otaUrl = "http://10.1.0.3";
int8_t otaPrecentageComplete = -1;
int16_t otaPort = 3232;
int16_t otaPort = HASP_OTA_PORT;
void otaProgress()
{

View File

@ -98,7 +98,7 @@ void TASMO_DATA_RECEIVE(char *data)
Log.verbose(F("TAS: dataType [%s]"), dataType);
if (!strcmp(dataType, "p[")){ //
dispatchCommand(data);
dispatchTextLine(data);
} else if (!strcmp(dataType, "[\"")) {
dispatchJson(data);
} else {
@ -123,7 +123,7 @@ void TASMO_DATA_RECEIVE(char *data)
} else if (!strcmp(slvCmd, "clearpage")) {
dispatchClearPage(slvVal);
} else {
dispatchCommand(data);
dispatchTextLine(data);
}
}
}

View File

@ -5,7 +5,7 @@
#include "hasp_conf.h"
#include "hasp_spiffs.h"
#if HASP_USE_SPIFFS>0
#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
@ -69,20 +69,31 @@ void spiffsInfo()
void spiffsList()
{
Log.verbose(F("FILE: Listing files on the internal flash:"));
#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP8266)
if(!SPIFFS.begin()) {
#else
if(!SPIFFS.begin(true)) {
#endif
Log.error(F("FILE: Flash file system not mouted."));
} else {
Log.verbose(F("FILE: Listing files on the internal flash:"));
#if defined(ARDUINO_ARCH_ESP32)
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file) {
Log.verbose(F("FILE: * %s (%u bytes)"), file.name(), (uint32_t)file.size());
file = root.openNextFile();
}
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file) {
Log.verbose(F("FILE: * %s (%u bytes)"), file.name(), (uint32_t)file.size());
file = root.openNextFile();
}
#endif
#if defined(ARDUINO_ARCH_ESP8266)
Dir dir = SPIFFS.openDir("/");
while(dir.next()) {
Log.notice(F("FILE: * %s (%u bytes)"), dir.fileName().c_str(), (uint32_t)dir.fileSize());
Dir dir = SPIFFS.openDir("/");
while(dir.next()) {
Log.notice(F("FILE: * %s (%u bytes)"), dir.fileName().c_str(), (uint32_t)dir.fileSize());
}
#endif
}
#endif
}
@ -91,7 +102,7 @@ void spiffsSetup()
{
// no SPIFFS settings, as settings depend on SPIFFS
#if HASP_USE_SPIFFS>0
#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP8266)
if(!SPIFFS.begin()) {
#else

View File

@ -77,7 +77,7 @@ void telnetAcceptClient()
telnetClient.stop(); // client disconnected
Log.unregisterOutput(1); // telnetClient
}
telnetClient = telnetServer.available(); // ready for new client
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"));
@ -146,10 +146,10 @@ static void telnetProcessLine()
}
default:
if(telnetInputIndex > 0) {
if(strcmp_P(telnetInputBuffer, PSTR("exit")) == 0) {
if(strcasecmp_P(telnetInputBuffer, PSTR("exit")) == 0) {
telnetClientDisconnect();
} else {
dispatchCommand(telnetInputBuffer);
dispatchTextLine(telnetInputBuffer);
}
}
}
@ -199,7 +199,7 @@ void telnetSetup()
#if defined(STM32F4xx)
// if(!telnetServer) telnetServer = new EthernetServer(telnetPort);
// if(telnetServer) {
telnetServer.begin();
telnetServer->begin();
Log.notice(F("Debug telnet console started"));
// } else {
// Log.error(F("Failed to start telnet server"));
@ -232,7 +232,7 @@ void IRAM_ATTR telnetLoop()
Ethernet.schedule();
// if(telnetServer)
{ // client is connected
EthernetClient client = telnetServer.available();
EthernetClient client = telnetServer->available();
if(client) {
if(!telnetClient || !telnetClient.connected()) {
//telnetAcceptClient(client);

View File

@ -51,12 +51,11 @@ void tftShowConfig(TFT_eSPI & tft)
tft.getSetup(tftSetup);
Log.verbose(F("TFT: TFT_eSPI : v%s"), tftSetup.version.c_str());
// #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
// Log.verbose(F("TFT: Processor : ESP%x"), tftSetup.esp);
// #else
// Log.verbose(F("TFT: Processor : STM%x"), tftSetup.esp);
// #endif
Log.verbose(F("TFT: Processor : %s"), halGetChipModel().c_str());
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
Log.verbose(F("TFT: Processor : ESP%x"), tftSetup.esp);
#else
Log.verbose(F("TFT: Processor : STM%x"), tftSetup.esp);
#endif
Log.verbose(F("TFT: CPU freq. : %i MHz"), halGetCpuFreqMHz());
#if defined(ARDUINO_ARCH_ESP8266)

View File

@ -153,6 +153,18 @@ bool wifiShowAP(char * ssid, char * pass)
return true;
}
void wifiReconnect()
{
WiFi.disconnect(true);
#if defined(ARDUINO_ARCH_ESP8266)
WiFi.hostname(mqttGetNodename().c_str());
#elif defined(ARDUINO_ARCH_ESP32)
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
WiFi.setHostname(mqttGetNodename().c_str());
#endif
WiFi.begin(wifiSsid, wifiPassword);
}
void wifiSetup()
{
#if defined(STM32F4xx)
@ -202,12 +214,12 @@ void wifiSetup()
gotIpEventHandler = WiFi.onStationModeGotIP(wifiSTAGotIP); // As soon WiFi is connected, start NTP Client
disconnectedEventHandler = WiFi.onStationModeDisconnected(wifiSTADisconnected);
WiFi.setSleepMode(WIFI_NONE_SLEEP);
#endif
#if defined(ARDUINO_ARCH_ESP32)
#elif defined(ARDUINO_ARCH_ESP32)
WiFi.onEvent(wifi_callback);
WiFi.setSleep(false);
#endif
WiFi.begin(wifiSsid, wifiPassword);
wifiReconnect();
Log.notice(F("WIFI: Connecting to : %s"), wifiSsid);
}
#endif
@ -232,7 +244,9 @@ bool wifiEvery5Seconds()
dispatchReboot(false);
}
Log.warning(F("WIFI: No Connection... retry %u"), wifiReconnectCounter);
if(wifiReconnectCounter % 6 == 0) WiFi.begin(wifiSsid, wifiPassword);
if(wifiReconnectCounter % 6 == 0) {
wifiReconnect();
}
return false;
}
}

View File

@ -1,519 +0,0 @@
/**
* @file lv_theme_hasp.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_themes/lv_theme.h"
#if LV_USE_THEME_HASP
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static lv_theme_t theme;
static lv_style_t def;
static lv_style_t scr;
/*Static style definitions*/
static lv_style_t sb;
static lv_style_t plain_bordered;
static lv_style_t label_prim;
static lv_style_t label_sec;
static lv_style_t label_hint;
// static lv_style_t btn_rel, btn_pr, btn_trel, btn_tpr, btn_ina;
/*Saved input parameters*/
static uint16_t _hue;
static lv_font_t * _font;
/**********************
* MACROS
**********************/
/**********************
* STATIC FUNCTIONS
**********************/
static void basic_init(void)
{
lv_style_plain.text.font = _font;
lv_style_pretty.text.font = _font;
lv_style_pretty_color.text.font = _font;
lv_style_btn_rel.text.font = _font;
lv_style_btn_pr.text.font = _font;
lv_style_btn_tgl_rel.text.font = _font;
lv_style_btn_tgl_pr.text.font = _font;
lv_style_btn_ina.text.font = _font;
if(_hue <= 360) {
lv_style_pretty_color.body.main_color = lv_color_hsv_to_rgb(_hue, 10, 70);
lv_style_pretty_color.body.grad_color = lv_color_hsv_to_rgb(_hue, 80, 80);
lv_style_plain_color.body.main_color = lv_color_hsv_to_rgb(_hue, 50, 75);
lv_style_plain_color.body.grad_color = lv_style_plain_color.body.main_color;
lv_style_btn_rel.body.main_color = lv_color_hsv_to_rgb(_hue, 10, 70);
lv_style_btn_rel.body.grad_color = lv_color_hsv_to_rgb(_hue, 80, 80);
lv_style_btn_pr.body.main_color = lv_color_hsv_to_rgb(_hue, 80, 70);
lv_style_btn_pr.body.grad_color = lv_color_hsv_to_rgb(_hue, 10, 80);
lv_style_btn_tgl_rel.body.main_color = lv_color_hsv_to_rgb(_hue, 80, 70);
lv_style_btn_tgl_rel.body.grad_color = lv_color_hsv_to_rgb(_hue, 10, 80);
lv_style_btn_tgl_pr.body.main_color = lv_color_hsv_to_rgb(_hue, 10, 70);
lv_style_btn_tgl_pr.body.grad_color = lv_color_hsv_to_rgb(_hue, 80, 80);
}
lv_style_copy(&def, &lv_style_pretty); /*Initialize the default style*/
def.text.font = _font;
lv_style_copy(&scr, &def);
scr.body.padding.bottom = 0;
scr.body.padding.top = 0;
scr.body.padding.left = 0;
scr.body.padding.right = 0;
lv_style_copy(&sb, &lv_style_pretty_color);
sb.body.grad_color = sb.body.main_color;
sb.body.padding.right = sb.body.padding.right / 2; /*Make closer to the edges*/
sb.body.padding.bottom = sb.body.padding.bottom / 2;
lv_style_copy(&plain_bordered, &lv_style_plain);
plain_bordered.body.border.width = 2;
plain_bordered.body.border.color = lv_color_hex3(0xbbb);
theme.style.bg = &lv_style_plain;
theme.style.scr = &scr;
theme.style.panel = &lv_style_pretty;
}
static void btn_init(void)
{
#if LV_USE_BTN != 0
theme.style.btn.rel = &lv_style_btn_rel;
theme.style.btn.pr = &lv_style_btn_pr;
theme.style.btn.tgl_rel = &lv_style_btn_tgl_rel;
theme.style.btn.tgl_pr = &lv_style_btn_tgl_pr;
theme.style.btn.ina = &lv_style_btn_ina;
#endif
}
static void label_init(void)
{
#if LV_USE_LABEL != 0
lv_style_copy(&label_prim, &lv_style_plain);
lv_style_copy(&label_sec, &lv_style_plain);
lv_style_copy(&label_hint, &lv_style_plain);
label_prim.text.color = lv_color_hex3(0x111);
label_sec.text.color = lv_color_hex3(0x888);
label_hint.text.color = lv_color_hex3(0xaaa);
theme.style.label.prim = &label_prim;
theme.style.label.sec = &label_sec;
theme.style.label.hint = &label_hint;
#endif
}
static void img_init(void)
{
#if LV_USE_IMG != 0
theme.style.img.light = &def;
theme.style.img.dark = &def;
#endif
}
static void line_init(void)
{
#if LV_USE_LINE != 0
theme.style.line.decor = &def;
#endif
}
static void led_init(void)
{
#if LV_USE_LED != 0
static lv_style_t led;
lv_style_copy(&led, &lv_style_pretty_color);
led.body.shadow.width = LV_DPI / 10;
led.body.radius = LV_RADIUS_CIRCLE;
led.body.border.width = LV_DPI / 30;
led.body.border.opa = LV_OPA_30;
led.body.shadow.color = led.body.main_color;
theme.style.led = &led;
#endif
}
static void bar_init(void)
{
#if LV_USE_BAR
theme.style.bar.bg = &lv_style_pretty;
theme.style.bar.indic = &lv_style_pretty_color;
#endif
}
static void slider_init(void)
{
#if LV_USE_SLIDER != 0
static lv_style_t slider_bg;
lv_style_copy(&slider_bg, &lv_style_pretty);
slider_bg.body.padding.left = LV_DPI / 20;
slider_bg.body.padding.right = LV_DPI / 20;
slider_bg.body.padding.top = LV_DPI / 20;
slider_bg.body.padding.bottom = LV_DPI / 20;
theme.style.slider.bg = &slider_bg;
theme.style.slider.indic = &lv_style_pretty_color;
theme.style.slider.knob = &lv_style_pretty;
#endif
}
static void sw_init(void)
{
#if LV_USE_SW != 0
static lv_style_t sw_indic, sw_bg;
lv_style_copy(&sw_indic, &lv_style_pretty_color);
sw_indic.body.padding.left = -0;
sw_indic.body.padding.right = -0;
sw_indic.body.padding.top = -0;
sw_indic.body.padding.bottom = -0;
sw_indic.body.padding.inner = -0;
lv_style_copy(&sw_bg, &lv_style_pretty);
sw_bg.body.padding.left = -0;
sw_bg.body.padding.right = -0;
sw_bg.body.padding.top = -0;
sw_bg.body.padding.bottom = -0;
sw_bg.body.padding.inner = -0;
theme.style.sw.bg = &sw_bg;
theme.style.sw.indic = &sw_indic;
theme.style.sw.knob_off = &lv_style_pretty;
theme.style.sw.knob_on = &lv_style_pretty;
#endif
}
static void lmeter_init(void)
{
#if LV_USE_LMETER != 0
static lv_style_t lmeter;
lv_style_copy(&lmeter, &lv_style_pretty_color);
lmeter.line.color = lv_color_hex3(0xddd);
lmeter.line.width = 2;
lmeter.body.main_color = lv_color_mix(lmeter.body.main_color, LV_COLOR_WHITE, LV_OPA_50);
lmeter.body.grad_color = lv_color_mix(lmeter.body.grad_color, LV_COLOR_BLACK, LV_OPA_50);
theme.style.lmeter = &lmeter;
#endif
}
static void gauge_init(void)
{
#if LV_USE_GAUGE != 0
static lv_style_t gauge;
lv_style_copy(&gauge, theme.style.lmeter);
gauge.line.color = theme.style.lmeter->body.grad_color;
gauge.line.width = 2;
gauge.body.main_color = lv_color_hex3(0x888);
gauge.body.grad_color = theme.style.lmeter->body.main_color;
gauge.text.color = lv_color_hex3(0x888);
gauge.text.font = _font;
theme.style.gauge = &gauge;
#endif
}
static void chart_init(void)
{
#if LV_USE_CHART
theme.style.chart = &lv_style_pretty;
#endif
}
static void cb_init(void)
{
#if LV_USE_CB != 0
theme.style.cb.bg = &lv_style_transp;
theme.style.cb.box.rel = &lv_style_pretty;
theme.style.cb.box.pr = &lv_style_btn_pr;
theme.style.cb.box.tgl_rel = &lv_style_btn_tgl_rel;
theme.style.cb.box.tgl_pr = &lv_style_btn_tgl_pr;
theme.style.cb.box.ina = &lv_style_btn_ina;
#endif
}
static void btnm_init(void)
{
#if LV_USE_BTNM
theme.style.btnm.bg = &lv_style_pretty;
theme.style.btnm.btn.rel = &lv_style_btn_rel;
theme.style.btnm.btn.pr = &lv_style_btn_pr;
theme.style.btnm.btn.tgl_rel = &lv_style_btn_tgl_rel;
theme.style.btnm.btn.tgl_pr = &lv_style_btn_tgl_pr;
theme.style.btnm.btn.ina = &lv_style_btn_ina;
#endif
}
static void kb_init(void)
{
#if LV_USE_KB
theme.style.kb.bg = &lv_style_pretty;
theme.style.kb.btn.rel = &lv_style_btn_rel;
theme.style.kb.btn.pr = &lv_style_btn_pr;
theme.style.kb.btn.tgl_rel = &lv_style_btn_tgl_rel;
theme.style.kb.btn.tgl_pr = &lv_style_btn_tgl_pr;
theme.style.kb.btn.ina = &lv_style_btn_ina;
#endif
}
static void mbox_init(void)
{
#if LV_USE_MBOX
theme.style.mbox.bg = &lv_style_pretty;
theme.style.mbox.btn.bg = &lv_style_transp;
theme.style.mbox.btn.rel = &lv_style_btn_rel;
theme.style.mbox.btn.pr = &lv_style_btn_tgl_pr;
#endif
}
static void page_init(void)
{
#if LV_USE_PAGE
theme.style.page.bg = &lv_style_pretty;
theme.style.page.scrl = &lv_style_transp_tight;
theme.style.page.sb = &sb;
#endif
}
static void ta_init(void)
{
#if LV_USE_TA
theme.style.ta.area = &lv_style_pretty;
theme.style.ta.oneline = &lv_style_pretty;
theme.style.ta.cursor = NULL;
theme.style.ta.sb = &sb;
#endif
}
static void list_init(void)
{
#if LV_USE_LIST != 0
theme.style.list.bg = &lv_style_pretty;
theme.style.list.scrl = &lv_style_transp_fit;
theme.style.list.sb = &sb;
theme.style.list.btn.rel = &lv_style_btn_rel;
theme.style.list.btn.pr = &lv_style_btn_pr;
theme.style.list.btn.tgl_rel = &lv_style_btn_tgl_rel;
theme.style.list.btn.tgl_pr = &lv_style_btn_tgl_pr;
theme.style.list.btn.ina = &lv_style_btn_ina;
#endif
}
static void ddlist_init(void)
{
#if LV_USE_DDLIST != 0
theme.style.ddlist.bg = &lv_style_pretty;
theme.style.ddlist.sel = &lv_style_plain_color;
theme.style.ddlist.sb = &sb;
#endif
}
static void roller_init(void)
{
#if LV_USE_ROLLER != 0
theme.style.roller.bg = &lv_style_pretty;
theme.style.roller.sel = &lv_style_plain_color;
#endif
}
static void tabview_init(void)
{
#if LV_USE_TABVIEW != 0
theme.style.tabview.bg = &plain_bordered;
theme.style.tabview.indic = &lv_style_plain_color;
theme.style.tabview.btn.bg = &lv_style_transp;
theme.style.tabview.btn.rel = &lv_style_btn_rel;
theme.style.tabview.btn.pr = &lv_style_btn_pr;
theme.style.tabview.btn.tgl_rel = &lv_style_btn_tgl_rel;
theme.style.tabview.btn.tgl_pr = &lv_style_btn_tgl_pr;
#endif
}
static void table_init(void)
{
#if LV_USE_TABLE != 0
theme.style.table.bg = &lv_style_transp_tight;
theme.style.table.cell = &lv_style_plain;
#endif
}
static void win_init(void)
{
#if LV_USE_WIN != 0
theme.style.win.bg = &plain_bordered;
theme.style.win.sb = &sb;
theme.style.win.header = &lv_style_plain_color;
theme.style.win.content = &lv_style_transp;
theme.style.win.btn.rel = &lv_style_btn_rel;
theme.style.win.btn.pr = &lv_style_btn_pr;
#endif
}
#if LV_USE_GROUP
static void style_mod(lv_group_t * group, lv_style_t * style)
{
(void)group; /*Unused*/
#if LV_COLOR_DEPTH != 1
/*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_ORANGE;
/*If not empty or has border then emphasis the border*/
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);
style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);
#else
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_BLACK;
style->body.border.width = 2;
#endif
}
static void style_mod_edit(lv_group_t * group, lv_style_t * style)
{
(void)group; /*Unused*/
#if LV_COLOR_DEPTH != 1
/*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_GREEN;
/*If not empty or has border then emphasis the border*/
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);
style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);
#else
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_BLACK;
style->body.border.width = 3;
#endif
}
#endif /*LV_USE_GROUP*/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the default theme
* @param hue [0..360] hue value from HSV color space to define the theme's base color
* @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme
*/
lv_theme_t * lv_theme_hasp_init(uint16_t hue, lv_font_t * font)
{
if(font == NULL) font = LV_FONT_DEFAULT;
_hue = hue;
_font = font;
/*For backward compatibility initialize all theme elements with a default style */
uint16_t i;
lv_style_t ** style_p = (lv_style_t **)&theme.style;
for(i = 0; i < LV_THEME_STYLE_COUNT; i++) {
*style_p = &def;
style_p++;
}
basic_init();
btn_init();
label_init();
img_init();
line_init();
led_init();
bar_init();
slider_init();
sw_init();
lmeter_init();
gauge_init();
chart_init();
cb_init();
btnm_init();
kb_init();
mbox_init();
page_init();
ta_init();
list_init();
ddlist_init();
roller_init();
tabview_init();
table_init();
win_init();
#if LV_USE_GROUP
theme.group.style_mod_xcb = style_mod;
theme.group.style_mod_edit_xcb = style_mod_edit;
#endif
return &theme;
}
/**
* Get a pointer to the theme
* @return pointer to the theme
*/
lv_theme_t * lv_theme_get_hasp(void)
{
return &theme;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

860
src/lv_theme_hasp.cpp Normal file
View File

@ -0,0 +1,860 @@
/**
* @file lv_theme_hasp.cpp
*
*/
/*********************
* INCLUDES
*********************/
#include "lvgl.h" /*To see all the widgets*/
#if LV_USE_THEME_HASP
#include "lv_misc/lv_gc.h"
#include "lv_theme_hasp.h"
#if defined(LV_GC_INCLUDE)
#include LV_GC_INCLUDE
#endif /* LV_ENABLE_GC */
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct
{
lv_style_t bg;
lv_style_t btn;
lv_style_t round;
lv_style_t color;
lv_style_t gray;
lv_style_t tick_line;
lv_style_t tight;
} theme_styles_t;
/**********************
* STATIC PROTOTYPES
**********************/
static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name);
/**********************
* STATIC VARIABLES
**********************/
static lv_theme_t theme;
static theme_styles_t * styles;
static bool inited;
/**********************
* MACROS
**********************/
/**********************
* STATIC FUNCTIONS
**********************/
static void style_init_reset(lv_style_t * style);
static void basic_init(void)
{
style_init_reset(&styles->bg);
lv_style_set_bg_opa(&styles->bg, LV_STATE_DEFAULT, LV_OPA_COVER);
lv_style_set_border_width(&styles->bg, LV_STATE_DEFAULT, 1);
lv_style_set_border_width(&styles->bg, LV_STATE_FOCUSED, 2);
lv_style_set_border_color(&styles->bg, LV_STATE_FOCUSED, theme.color_secondary);
lv_style_set_border_color(&styles->bg, LV_STATE_EDITED, lv_color_darken(theme.color_secondary, LV_OPA_30));
lv_style_set_line_width(&styles->bg, LV_STATE_DEFAULT, 1);
lv_style_set_scale_end_line_width(&styles->bg, LV_STATE_DEFAULT, 1);
lv_style_set_scale_end_color(&styles->bg, LV_STATE_DEFAULT, theme.color_primary);
lv_style_set_text_color(&styles->bg, LV_STATE_DEFAULT, LV_COLOR_BLACK);
lv_style_set_text_font(&styles->bg, LV_STATE_DEFAULT, theme.font_normal);
lv_style_set_pad_left(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
lv_style_set_pad_right(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
lv_style_set_pad_top(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
lv_style_set_pad_bottom(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
lv_style_set_pad_inner(&styles->bg, LV_STATE_DEFAULT, LV_DPI / 10);
lv_style_set_value_font(&styles->bg, LV_STATE_DEFAULT, theme.font_normal);
style_init_reset(&styles->btn);
lv_style_set_bg_color(&styles->btn, LV_STATE_PRESSED, lv_color_hex3(0xccc));
lv_style_set_bg_color(&styles->btn, LV_STATE_CHECKED, theme.color_primary);
lv_style_set_bg_color(&styles->btn, LV_STATE_CHECKED | LV_STATE_PRESSED,
lv_color_darken(theme.color_primary, LV_OPA_30));
lv_style_set_bg_color(&styles->btn, LV_STATE_DISABLED, LV_COLOR_SILVER);
lv_style_set_text_color(&styles->btn, LV_STATE_DISABLED, LV_COLOR_GRAY);
lv_style_set_image_recolor(&styles->btn, LV_STATE_DISABLED, LV_COLOR_GRAY);
style_init_reset(&styles->round);
lv_style_set_radius(&styles->round, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
style_init_reset(&styles->color);
lv_style_set_bg_color(&styles->color, LV_STATE_DEFAULT, theme.color_primary);
lv_style_set_line_color(&styles->color, LV_STATE_DEFAULT, theme.color_primary);
style_init_reset(&styles->gray);
lv_style_set_bg_color(&styles->gray, LV_STATE_DEFAULT, LV_COLOR_SILVER);
lv_style_set_line_color(&styles->gray, LV_STATE_DEFAULT, LV_COLOR_SILVER);
lv_style_set_text_color(&styles->gray, LV_STATE_DEFAULT, LV_COLOR_GRAY);
style_init_reset(&styles->tick_line);
lv_style_set_line_width(&styles->tick_line, LV_STATE_DEFAULT, 5);
lv_style_set_scale_end_line_width(&styles->tick_line, LV_STATE_DEFAULT, 5);
lv_style_set_scale_end_color(&styles->tick_line, LV_STATE_DEFAULT, theme.color_primary);
style_init_reset(&styles->tight);
lv_style_set_pad_left(&styles->tight, LV_STATE_DEFAULT, 0);
lv_style_set_pad_right(&styles->tight, LV_STATE_DEFAULT, 0);
lv_style_set_pad_top(&styles->tight, LV_STATE_DEFAULT, 0);
lv_style_set_pad_bottom(&styles->tight, LV_STATE_DEFAULT, 0);
lv_style_set_pad_inner(&styles->tight, LV_STATE_DEFAULT, 0);
}
static void arc_init(void)
{
#if LV_USE_ARC != 0
#endif
}
static void bar_init(void)
{
#if LV_USE_BAR
#endif
}
static void btn_init(void)
{
#if LV_USE_BTN != 0
#endif
}
static void btnmatrix_init(void)
{
#if LV_USE_BTNMATRIX
#endif
}
static void calendar_init(void)
{
#if LV_USE_CALENDAR
#endif
}
static void chart_init(void)
{
#if LV_USE_CHART
#endif
}
static void cpicker_init(void)
{
#if LV_USE_CPICKER
#endif
}
static void checkbox_init(void)
{
#if LV_USE_CHECKBOX != 0
#endif
}
static void cont_init(void)
{
#if LV_USE_CONT != 0
#endif
}
static void gauge_init(void)
{
#if LV_USE_GAUGE != 0
#endif
}
static void img_init(void)
{
#if LV_USE_IMG != 0
#endif
}
static void label_init(void)
{
#if LV_USE_LABEL != 0
#endif
}
static void linemeter_init(void)
{
#if LV_USE_LINEMETER != 0
#endif
}
static void line_init(void)
{
#if LV_USE_LINE != 0
#endif
}
static void led_init(void)
{
#if LV_USE_LED != 0
#endif
}
static void page_init(void)
{
#if LV_USE_PAGE
#endif
}
static void slider_init(void)
{
#if LV_USE_SLIDER != 0
#endif
}
static void switch_init(void)
{
#if LV_USE_SWITCH != 0
#endif
}
static void spinbox_init(void)
{
#if LV_USE_SPINBOX
#endif
}
static void spinner_init(void)
{
#if LV_USE_SPINNER != 0
#endif
}
static void keyboard_init(void)
{
#if LV_USE_KEYBOARD
#endif
}
static void msgbox_init(void)
{
#if LV_USE_MSGBOX
#endif
}
static void textarea_init(void)
{
#if LV_USE_TEXTAREA
#endif
}
static void list_init(void)
{
#if LV_USE_LIST != 0
#endif
}
static void ddlist_init(void)
{
#if LV_USE_DROPDOWN != 0
#endif
}
static void roller_init(void)
{
#if LV_USE_ROLLER != 0
#endif
}
static void tabview_init(void)
{
#if LV_USE_TABVIEW != 0
#endif
}
static void tileview_init(void)
{
#if LV_USE_TILEVIEW != 0
#endif
}
static void table_init(void)
{
#if LV_USE_TABLE != 0
#endif
}
static void win_init(void)
{
#if LV_USE_WIN != 0
#endif
}
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the default
* @param color_primary the primary color of the theme
* @param color_secondary the secondary color for the theme
* @param flags ORed flags starting with `LV_THEME_DEF_FLAG_...`
* @param font_small pointer to a small font
* @param font_normal pointer to a normal font
* @param font_subtitle pointer to a large font
* @param font_title pointer to a extra large font
* @return a pointer to reference this theme later
*/
lv_theme_t * lv_theme_hasp_init(lv_color_t color_primary, lv_color_t color_secondary, uint32_t flags,
const lv_font_t * font_small, const lv_font_t * font_normal,
const lv_font_t * font_subtitle, const lv_font_t * font_title)
{
/* This trick is required only to avoid the garbage collection of
* styles' data if LVGL is used in a binding (e.g. Micropython)
* In a general case styles could be simple `static lv_style_t my style` variables or allocated directly into
* `styles`*/
if(!inited) {
#if defined(LV_GC_INCLUDE)
LV_GC_ROOT(_lv_theme_template_styles) = lv_mem_alloc(sizeof(theme_styles_t));
styles = (theme_styles_t *)LV_GC_ROOT(_lv_theme_template_styles);
#else
styles = (theme_styles_t*)lv_mem_alloc(sizeof(theme_styles_t));
#endif
}
theme.color_primary = color_primary;
theme.color_secondary = color_secondary;
theme.font_small = font_small;
theme.font_normal = font_normal;
theme.font_subtitle = font_subtitle;
theme.font_title = font_title;
theme.flags = flags;
basic_init();
cont_init();
btn_init();
label_init();
bar_init();
img_init();
line_init();
led_init();
slider_init();
switch_init();
linemeter_init();
gauge_init();
arc_init();
spinner_init();
chart_init();
calendar_init();
cpicker_init();
checkbox_init();
btnmatrix_init();
keyboard_init();
msgbox_init();
page_init();
textarea_init();
spinbox_init();
list_init();
ddlist_init();
roller_init();
tabview_init();
tileview_init();
table_init();
win_init();
theme.apply_xcb = NULL;
theme.apply_cb = theme_apply;
return &theme;
}
void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
{
LV_UNUSED(th);
lv_style_list_t * list;
switch(name) {
case LV_THEME_NONE:
break;
case LV_THEME_SCR:
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tight);
break;
case LV_THEME_OBJ:
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
break;
#if LV_USE_CONT
case LV_THEME_CONT:
list = lv_obj_get_style_list(obj, LV_CONT_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
break;
#endif
#if LV_USE_BTN
case LV_THEME_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_BTNMATRIX
case LV_THEME_BTNMATRIX:
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_KEYBOARD
case LV_THEME_KEYBOARD:
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_KEYBOARD_PART_BTN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_BAR
case LV_THEME_BAR:
list = lv_obj_get_style_list(obj, LV_BAR_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tight);
list = lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
break;
#endif
#if LV_USE_SWITCH
case LV_THEME_SWITCH:
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tight);
_lv_style_list_add_style(list, &styles->round);
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tight);
_lv_style_list_add_style(list, &styles->round);
break;
#endif
#if LV_USE_CANVAS
case LV_THEME_CANVAS:
list = lv_obj_get_style_list(obj, LV_CANVAS_PART_MAIN);
break;
#endif
#if LV_USE_IMG
case LV_THEME_IMAGE:
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
break;
#endif
#if LV_USE_IMGBTN
case LV_THEME_IMGBTN:
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
break;
#endif
#if LV_USE_LABEL
case LV_THEME_LABEL:
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
break;
#endif
#if LV_USE_LINE
case LV_THEME_LINE:
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
break;
#endif
#if LV_USE_ARC
case LV_THEME_ARC:
list = lv_obj_get_style_list(obj, LV_ARC_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tick_line);
_lv_style_list_add_style(list, &styles->round);
list = lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
_lv_style_list_add_style(list, &styles->tick_line);
break;
#endif
#if LV_USE_SPINNER
case LV_THEME_SPINNER:
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tick_line);
list = lv_obj_get_style_list(obj, LV_SPINNER_PART_INDIC);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
_lv_style_list_add_style(list, &styles->tick_line);
break;
#endif
#if LV_USE_SLIDER
case LV_THEME_SLIDER:
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->round);
break;
#endif
#if LV_USE_CHECKBOX
case LV_THEME_CHECKBOX:
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BG);
list = lv_obj_get_style_list(obj, LV_CHECKBOX_PART_BULLET);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_MSGBOX
case LV_THEME_MSGBOX:
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
break;
case LV_THEME_MSGBOX_BTNS:
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_MSGBOX_PART_BTN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_LED
case LV_THEME_LED:
list = lv_obj_get_style_list(obj, LV_LED_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
_lv_style_list_add_style(list, &styles->round);
break;
#endif
#if LV_USE_PAGE
case LV_THEME_PAGE:
list = lv_obj_get_style_list(obj, LV_PAGE_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->gray);
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLBAR);
_lv_style_list_add_style(list, &styles->bg);
break;
#endif
#if LV_USE_TABVIEW
case LV_THEME_TABVIEW:
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_BG_SCRLLABLE);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_INDIC);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
list = lv_obj_get_style_list(obj, LV_TABVIEW_PART_TAB_BTN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
case LV_THEME_TABVIEW_PAGE:
list = lv_obj_get_style_list(obj, LV_PAGE_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->gray);
list = lv_obj_get_style_list(obj, LV_PAGE_PART_SCROLLABLE);
_lv_style_list_add_style(list, &styles->bg);
break;
#endif
#if LV_USE_TILEVIEW
case LV_THEME_TILEVIEW:
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_SCROLLBAR);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_TILEVIEW_PART_EDGE_FLASH);
_lv_style_list_add_style(list, &styles->bg);
break;
#endif
#if LV_USE_ROLLER
case LV_THEME_ROLLER:
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_ROLLER_PART_SELECTED);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
break;
#endif
#if LV_USE_OBJMASK
case LV_THEME_OBJMASK:
list = lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN);
break;
#endif
#if LV_USE_LIST
case LV_THEME_LIST:
list = lv_obj_get_style_list(obj, LV_LIST_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLABLE);
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLBAR);
_lv_style_list_add_style(list, &styles->bg);
break;
case LV_THEME_LIST_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_DROPDOWN
case LV_THEME_DROPDOWN:
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SCROLLBAR);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->color);
break;
#endif
#if LV_USE_CHART
case LV_THEME_CHART:
list = lv_obj_get_style_list(obj, LV_CHART_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_CHART_PART_SERIES);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tight);
break;
#endif
#if LV_USE_TABLE
case LV_THEME_TABLE: {
list = lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
int idx = 1; /* start value should be 1, not zero, since cell styles
start at 1 due to presence of LV_TABLE_PART_BG=0
in the enum (lv_table.h) */
/* declaring idx outside loop to work with older compilers */
for(; idx <= LV_TABLE_CELL_STYLE_CNT; idx++) {
list = lv_obj_get_style_list(obj, idx);
_lv_style_list_add_style(list, &styles->bg);
}
break;
}
#endif
#if LV_USE_WIN
case LV_THEME_WIN:
list = lv_obj_get_style_list(obj, LV_WIN_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_WIN_PART_SCROLLBAR);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_WIN_PART_CONTENT_SCROLLABLE);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_WIN_PART_HEADER);
_lv_style_list_add_style(list, &styles->bg);
break;
case LV_THEME_WIN_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_TEXTAREA
case LV_THEME_TEXTAREA:
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_PLACEHOLDER);
_lv_style_list_add_style(list, &styles->gray);
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tight);
list = lv_obj_get_style_list(obj, LV_TEXTAREA_PART_SCROLLBAR);
_lv_style_list_add_style(list, &styles->bg);
break;
#endif
#if LV_USE_SPINBOX
case LV_THEME_SPINBOX:
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_SPINBOX_PART_CURSOR);
_lv_style_list_add_style(list, &styles->bg);
break;
case LV_THEME_SPINBOX_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
break;
#endif
#if LV_USE_CALENDAR
case LV_THEME_CALENDAR:
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_BG);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DATE);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->btn);
_lv_style_list_add_style(list, &styles->tight);
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_HEADER);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_CALENDAR_PART_DAY_NAMES);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->tight);
break;
#endif
#if LV_USE_CPICKER
case LV_THEME_CPICKER:
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
list = lv_obj_get_style_list(obj, LV_CPICKER_PART_KNOB);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->round);
break;
#endif
#if LV_USE_LINEMETER
case LV_THEME_LINEMETER:
list = lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->round);
break;
#endif
#if LV_USE_GAUGE
case LV_THEME_GAUGE:
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAIN);
_lv_style_list_add_style(list, &styles->bg);
_lv_style_list_add_style(list, &styles->round);
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_MAJOR);
_lv_style_list_add_style(list, &styles->tick_line);
list = lv_obj_get_style_list(obj, LV_GAUGE_PART_NEEDLE);
_lv_style_list_add_style(list, &styles->bg);
break;
#endif
default:
break;
}
lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
}
/**********************
* STATIC FUNCTIONS
**********************/
static void style_init_reset(lv_style_t * style)
{
if(inited)
lv_style_reset(style);
else
lv_style_init(style);
}
#endif

View File

@ -1,5 +1,5 @@
/**
* @file lv_theme_default.h
* @file lv_theme_hasp.h
*
*/
@ -13,8 +13,7 @@ extern "C" {
/*********************
* INCLUDES
*********************/
#include "lvgl.h"
//#include "../lib/lvgl/src/lv_conf_internal.h"
#include "lv_conf.h"
#if LV_USE_THEME_HASP
@ -31,19 +30,19 @@ extern "C" {
**********************/
/**
* Initialize the default theme
* @param hue [0..360] hue value from HSV color space to define the theme's base color
* @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme
* Initialize the default
* @param color_primary the primary color of the theme
* @param color_secondary the secondary color for the theme
* @param flags ORed flags starting with `LV_THEME_DEF_FLAG_...`
* @param font_small pointer to a small font
* @param font_normal pointer to a normal font
* @param font_subtitle pointer to a large font
* @param font_title pointer to a extra large font
* @return a pointer to reference this theme later
*/
lv_theme_t * lv_theme_hasp_init(uint16_t hue, lv_font_t * font);
/**
* Get a pointer to the theme
* @return pointer to the theme
*/
lv_theme_t * lv_theme_get_hasp(void);
lv_theme_t * lv_theme_hasp_init(lv_color_t color_primary, lv_color_t color_secondary, uint32_t flags,
const lv_font_t * font_small, const lv_font_t * font_normal,
const lv_font_t * font_subtitle, const lv_font_t * font_title);
/**********************
* MACROS
**********************/
@ -54,4 +53,4 @@ lv_theme_t * lv_theme_get_hasp(void);
} /* extern "C" */
#endif
#endif /*LV_THEME_TEMPL_H*/
#endif /*LV_THEME_HASP_H*/

View File

@ -42,33 +42,34 @@ void setup()
* Apply User Configuration
***************************/
debugSetup();
guiSetup();
#if HASP_USE_GPIO > 0
gpioSetup();
#endif
#if HASP_USE_WIFI > 0
wifiSetup();
#endif
oobeSetup();
haspSetup();
#if HASP_USE_MDNS > 0
mdnsSetup();
#endif
#if HASP_USE_OTA > 0
otaSetup();
#endif
#if HASP_USE_ETHERNET > 0
ethernetSetup();
#endif
#if HASP_USE_MQTT > 0
mqttSetup();
mqttSetup(); // Load Hostname before starting WiFi
#endif
#if HASP_USE_WIFI > 0
wifiSetup();
#endif
guiSetup();
if(!oobeSetup()) {
haspSetup();
}
#if HASP_USE_MDNS > 0
mdnsSetup();
#endif
#if HASP_USE_OTA > 0
otaSetup();
#endif
#if HASP_USE_HTTP > 0
@ -108,18 +109,19 @@ void loop()
/* Graphics Loops */
// tftLoop();
guiLoop();
/* Application Loops */
// haspLoop();
debugLoop();
#if HASP_USE_GPIO > 0
gpioLoop();
#endif
#endif // GPIO
/* Network Services Loops */
#if HASP_USE_ETHERNET > 0
ethernetLoop();
#endif
#endif // ETHERNET
#if HASP_USE_MQTT > 0
mqttLoop();
@ -145,8 +147,6 @@ void loop()
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 */

28
test/connect.robot Normal file
View File

@ -0,0 +1,28 @@
*** Settings ***
| Library | String
| Library | MQTTLibrary
| Test Timeout | 30 seconds
*** Variables ***
| ${broker.uri} | 10.4.0.5
| ${broker.port} | 1883
| ${client.id} | test.client
| *Test Cases*
| Connect to a broker with default port and client id
| | ${mqttc} | Connect | ${broker.uri}
| | ${client_id} = | Decode Bytes To String | ${mqttc._client_id} | UTF-8
| | Should Be Empty | ${client_id} |
| | [Teardown] | Disconnect
| Connect to a broker with default port and specified client id
| | ${mqttc} | Connect | ${broker.uri} | client_id=${client.id}
| | Should be equal as strings | ${mqttc._client_id} | ${client.id}
| | [Teardown] | Disconnect
| Connect to a broker with specified port and client id
| | ${mqttc} | Connect | ${broker.uri} | ${broker.port} | ${client.id}
| | Should be equal as strings | ${mqttc._client_id} | ${client.id}
| | [Teardown] | Disconnect

185
test/hasp-lvgl.robot Normal file
View File

@ -0,0 +1,185 @@
| *Settings* | *Value*
| Resource | keywords.robot
| Test Timeout | 240 seconds
| *Keywords*
| Test Property
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
| | ... | ${property}=${property} | ${data}=${data}
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | hasp/platetelemetry/command
| | ${restopic} | Set Variable | hasp/platetelemetry/state/json
| | ${qos} | Set Variable | 1
| | ${message} | Set Variable | ${property}=${data}
| | ${result} | Set Variable | {"${property}":"${data}"}
| | Sleep | .01s
| | Subscribe Async | client.id=${client} | topic=${restopic}
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
| | Publish | ${topic} | ${message} | 1
| | Publish | ${topic} | ${property} | 1
| | log to console | ${result}
| | @{messages} | Listen and Get Messages | topic=${restopic} | limit=1 | timeout=1.5
| | LOG | ${messages}
| | Length Should Be | ${messages} | 1
| | Should Be Equal As Strings | ${messages}[0] | ${result}
| Test Page
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
| | ... | ${property}=${property} | ${data}=${data}
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | hasp/platetelemetry/command
| | ${restopic} | Set Variable | hasp/platetelemetry/state/page
| | ${qos} | Set Variable | 1
| | ${message} | Set Variable | ${property}=${data}
| | Subscribe Async | client.id=${client} | topic=${restopic}
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
| | Publish | ${topic} | ${message} | 1
| | Publish | ${topic} | ${property} | 1
| | @{messages} | Listen and Get Messages | topic=${restopic} | limit=1 | timeout=1
| | LOG | ${messages}
| | Length Should Be | ${messages} | 1
| | Should Be Equal As Strings | ${messages}[0] | ${data}
| Hasp Command
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
| | ... | ${property}=${property} | ${data}=${data}
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | hasp/platetelemetry/command/${property}
| | ${restopic} | Set Variable | hasp/platetelemetry/state/page
| | ${qos} | Set Variable | 1
| | ${message} | Set Variable | ${data}
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
| | Publish | ${topic} | ${message} | 1
| *Test Cases*
| Test Color Picker\n
| | ${obj} | Set Variable | p[1].b[4]
| | Test Page | property=page | data=1
| | Hasp Command | property=clearpage | data=1
| | Hasp Command | property=jsonl | data={"page":1,"id":4,"objid":20}
#| | Test Property | property=${obj}.txt | data=ABC
#| | Test Property | property=${obj}.txt | data=1234
| | Test Property | property=${obj}.x | data=50
| | Test Property | property=${obj}.x | data=60
| | Test Property | property=${obj}.y | data=70
| | Test Property | property=${obj}.y | data=80
| | Test Property | property=${obj}.w | data=80
| | Test Property | property=${obj}.w | data=100
| | Test Property | property=${obj}.h | data=80
| | Test Property | property=${obj}.h | data=100
| | Test Property | property=${obj}.hidden | data=1
| | Test Property | property=${obj}.hidden | data=0
| | Test Property | property=${obj}.vis | data=0
| | Test Property | property=${obj}.vis | data=1
| | Test Property | property=${obj}.enabled | data=0
| | Test Property | property=${obj}.enabled | data=1
| | Test Property | property=${obj}.opacity | data=0
| | Test Property | property=${obj}.opacity | data=64
| | Test Property | property=${obj}.opacity | data=192
| | Test Property | property=${obj}.opacity | data=255
#| | Test Property | property=${obj}.rect | data=1
#| | Test Property | property=${obj}.rect | data=0
| | Test Property | property=${obj}.val | data=50
| | Test Property | property=${obj}.val | data=60
| | Test Property | property=${obj}.val | data=70
| | Test Property | property=${obj}.val | data=80
| Test Text Field\n
| | ${obj} | Set Variable | p[1].b[1]
| | Test Page | property=page | data=1
| | Hasp Command | property=clearpage | data=1
| | Hasp Command | property=jsonl | data={"page":1,"id":1,"objid":12}
| | Test Property | property=${obj}.txt | data=ABC
| | Test Property | property=${obj}.txt | data=123
| | Test Property | property=${obj}.x | data=20
| | Test Property | property=${obj}.x | data=10
| | Test Property | property=${obj}.y | data=20
| | Test Property | property=${obj}.y | data=10
#| | Test Property | property=${obj}.w | data=80
#| | Test Property | property=${obj}.w | data=75
#| | Test Property | property=${obj}.h | data=36
#| | Test Property | property=${obj}.h | data=18
| | Test Property | property=${obj}.hidden | data=1
| | Test Property | property=${obj}.hidden | data=0
| | Test Property | property=${obj}.vis | data=0
| | Test Property | property=${obj}.vis | data=1
| | Test Property | property=${obj}.enabled | data=0
| | Test Property | property=${obj}.enabled | data=1
| | Test Property | property=${obj}.opacity | data=0
| | Test Property | property=${obj}.opacity | data=64
| | Test Property | property=${obj}.opacity | data=192
| | Test Property | property=${obj}.opacity | data=255
| Test Button\n
| | ${obj} | Set Variable | p[1].b[1]
| | Test Page | property=page | data=1
| | Hasp Command | property=clearpage | data=1
| | Hasp Command | property=jsonl | data={"page":1,"id":1,"objid":10}
#| | Test Property | property=${obj}.txt | data=ABC
#| | Test Property | property=${obj}.txt | data=1234
| | Test Property | property=${obj}.x | data=20
| | Test Property | property=${obj}.x | data=10
| | Test Property | property=${obj}.y | data=20
| | Test Property | property=${obj}.y | data=10
| | Test Property | property=${obj}.w | data=80
| | Test Property | property=${obj}.w | data=75
| | Test Property | property=${obj}.h | data=36
| | Test Property | property=${obj}.h | data=18
| | Test Property | property=${obj}.hidden | data=1
| | Test Property | property=${obj}.hidden | data=0
| | Test Property | property=${obj}.vis | data=0
| | Test Property | property=${obj}.vis | data=1
| | Test Property | property=${obj}.enabled | data=0
| | Test Property | property=${obj}.enabled | data=1
| | Test Property | property=${obj}.opacity | data=0
| | Test Property | property=${obj}.opacity | data=64
| | Test Property | property=${obj}.opacity | data=192
| | Test Property | property=${obj}.opacity | data=255
| | Test Property | property=${obj}.toggle | data=0
| | Test Property | property=${obj}.toggle | data=1
| | Test Property | property=${obj}.val | data=0
| | Test Property | property=${obj}.val | data=1
| | Test Property | property=${obj}.val | data=2
| | Test Property | property=${obj}.val | data=3
| Test Slider\n
| | ${obj} | Set Variable | p[1].b[4]
| | Test Page | property=page | data=1
| | Hasp Command | property=clearpage | data=1
| | Hasp Command | property=jsonl | data={"page":1,"id":4,"objid":30}
#| | Test Property | property=${obj}.txt | data=ABC
#| | Test Property | property=${obj}.txt | data=1234
| | Test Property | property=${obj}.x | data=20
| | Test Property | property=${obj}.x | data=10
| | Test Property | property=${obj}.y | data=20
| | Test Property | property=${obj}.y | data=10
| | Test Property | property=${obj}.w | data=80
| | Test Property | property=${obj}.w | data=75
| | Test Property | property=${obj}.h | data=36
| | Test Property | property=${obj}.h | data=18
| | Test Property | property=${obj}.hidden | data=1
| | Test Property | property=${obj}.hidden | data=0
| | Test Property | property=${obj}.vis | data=0
| | Test Property | property=${obj}.vis | data=1
| | Test Property | property=${obj}.enabled | data=0
| | Test Property | property=${obj}.enabled | data=1
| | Test Property | property=${obj}.opacity | data=0
| | Test Property | property=${obj}.opacity | data=64
| | Test Property | property=${obj}.opacity | data=192
| | Test Property | property=${obj}.opacity | data=255
| | Test Property | property=${obj}.max | data=200
| | Test Property | property=${obj}.min | data=100
| | Test Property | property=${obj}.min | data=50
| | Test Property | property=${obj}.max | data=150
| | Test Property | property=${obj}.val | data=50
| | Test Property | property=${obj}.val | data=60
| | Test Property | property=${obj}.val | data=70
| | Test Property | property=${obj}.val | data=80

91
test/keywords.robot Normal file
View File

@ -0,0 +1,91 @@
| *Settings* | *Value*
| Library | MQTTLibrary
| Library | BuiltIn
| *Variables* | *Value*
#| ${broker.uri} | mqtt.eclipse.org
| ${broker.uri} | 10.4.0.5
| ${broker.port} | 1883
| ${client.id} | mqtt.test.client
| ${topic} | test/mqtt_test
| ${sub.topic} | test/mqtt_test_sub
| *Keywords* |
| Easy Connect
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
| Publish to MQTT Broker
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
| | ... | ${topic}=${topic} | ${message}=${EMPTY}
| | ... | ${qos}=0 | ${retention}=${false}
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
| | Publish | ${topic} | ${message} | ${qos} | ${retention}
| Publish to MQTT Broker and Disconnect
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
| | ... | ${topic}=${topic} | ${message}=${EMPTY}
| | ... | ${qos}=0 | ${retention}=${false}
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
| | Publish | ${topic} | ${message} | ${qos} | ${retention}
| | [Teardown] | Disconnect
| Subscribe to MQTT Broker and Validate
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${topic}=${topic}
| | ... | ${message}=${EMPTY} | ${qos}=1
| | ... | ${timeout}=1s
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
| | Subscribe and Validate
| | ... | ${topic} | ${qos} | ${message} | ${timeout}
| | [Teardown] | Disconnect
| Subscribe and Get Messages
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${topic}=${topic}
| | ... | ${qos}=1 | ${timeout}=1s
| | ... | ${limit}=1
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
| | @{messages} | Subscribe | ${topic} | ${qos} | ${timeout} | ${limit}
| | [Teardown] | Disconnect
| | [Return] | @{messages}
| Subscribe Async
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${topic}=${topic}
| | ... | ${qos}=1 | ${timeout}=0s
| | ... | ${limit}=1
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
| | Subscribe | ${topic} | ${qos} | ${timeout} | ${limit}
| Unsubscribe and Disconnect
| | [Arguments] | ${topic}=${topic}
| | Unsubscribe | ${topic}
| | [Teardown] | Disconnect
| Unsubscribe Multiple and Disconnect
| | [Arguments] | @{topics}
| | FOR | ${topic} | IN | @{topics}
| | | Unsubscribe | ${topic}
| | END
| | [Teardown] | Disconnect
| Subscribe and Unsubscribe
| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
| | ... | ${client.id}=${client.id} | ${topic}=${topic}
| | ... | ${qos}=1 | ${timeout}=1s
| | ... | ${limit}=1
| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
| | @{messages} | Subscribe | ${topic} | ${qos} | ${timeout} | ${limit}
| | Unsubscribe | ${topic}
| | [Teardown] | Disconnect
| | [Return] | @{messages}
| Listen and Get Messages
| | [Arguments] | ${topic}=${topic} | ${timeout}=1s
| | ... | ${limit}=1
| | @{messages} | Listen | ${topic} | ${timeout} | ${limit}
| | [Return] | @{messages}

209
test/pubsub.robot Normal file
View File

@ -0,0 +1,209 @@
| *Settings* | *Value*
| Resource | keywords.robot
| Test Timeout | 30 seconds
| *Test Cases*
| Publish a non-empty message
| | ${time} | Get Time | epoch
| | ${message} | Catenate | test message | ${time}
| | Publish to MQTT Broker and Disconnect | message=${message}
| Publish an empty message
| | Publish to MQTT Broker and Disconnect
| Publish a message with QOS 1 and validate that the message is received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | ${message} | Set Variable | subscription test message
| | Run Keyword And Expect Error | The expected payload didn't arrive in the topic
| | ... | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic} | message=${message}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=${message} | qos=1
| | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic} | message=${message}
| Publish multiple messages and confirm that validation succeeds only after correct message is published
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | ${message} | Set Variable | subscription test message
| | Run Keyword And Expect Error | The expected payload didn't arrive in the topic
| | ... | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic} | message=${message}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=message1 | qos=1
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=message2 | qos=1
| | Run Keyword And Expect Error | The expected payload didn't arrive in the topic
| | ... | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic} | message=${message}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=${message} | qos=1
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=message3 | qos=1
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=message4 | qos=1
| | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic} | message=${message}
| Publish an empty message with QOS 1 and validate
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Run Keyword And Expect Error | The expected payload didn't arrive in the topic
| | ... | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | qos=1
| | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic}
| Publish and validate with regular expression
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | ${message} | Set Variable | subscription test message
| | ${regex} | Set Variable | ^subscription [test]{4} message$
| | Run Keyword And Expect Error | The expected payload didn't arrive in the topic
| | ... | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic} | message=whatever
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=${message} | qos=1
| | Subscribe to MQTT Broker and Validate | client.id=${client} | topic=${topic} | message=${regex}
| Subscribe for the first time and validate that no messages are received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | @{messages} | Subscribe and Get Messages | client.id=${client} | topic=${topic} | timeout=5s
| | LOG | ${messages}
| | Length Should Be | ${messages} | 0
| Subscribe, publish 1 message and validate it is received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Subscribe and Get Messages | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message | qos=1
| | @{messages} | Subscribe and Get Messages | client.id=${client} | topic=${topic}
| | LOG | ${messages}
| | Length Should Be | ${messages} | 1
| | Should Be Equal As Strings | ${messages}[0] | test message
| Subscribe with no limit, publish multiple messages and validate they are received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Subscribe and Get Messages | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message1 | qos=1
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message2 | qos=1
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message3 | qos=1
| | @{messages} | Subscribe and Get Messages | client.id=${client} | topic=${topic} | limit=0
| | LOG | ${messages}
| | Length Should Be | ${messages} | 3
| | Should Be Equal As Strings | ${messages}[0] | test message1
| | Should Be Equal As Strings | ${messages}[1] | test message2
| | Should Be Equal As Strings | ${messages}[2] | test message3
| Subscribe with limit
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Subscribe and Get Messages | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message1 | qos=1
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message2 | qos=1
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message3 | qos=1
| | @{messages} | Subscribe and Get Messages | client.id=${client} | topic=${topic} | limit=1
| | LOG | ${messages}
| | Length Should Be | ${messages} | 1
| | Should Be Equal As Strings | ${messages}[0] | test message1
| | @{messages} | Subscribe and Get Messages | client.id=${client} | topic=${topic} | limit=2
| | LOG | ${messages}
| | Length Should Be | ${messages} | 2
| | Should Be Equal As Strings | ${messages}[0] | test message2
| | Should Be Equal As Strings | ${messages}[1] | test message3
| Unsubscribe and validate no messages are received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Subscribe and Get Messages | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message1 | qos=1
| | @{messages} | Subscribe and Unsubscribe | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message2 | qos=1
| | @{messages} | Subscribe and Get Messages | client.id=${client} | topic=${topic}
| | LOG | ${messages}
| | Length Should Be | ${messages} | 0
| Publish and Subscribe to a broker that requires username, password authentication
| | [Tags] | auth
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test
| | ${message} | Set Variable | subscription test message
| | Set username and password | authuser1 | password1
| | Run Keyword And Expect Error | The expected payload didn't arrive in the topic
| | ... | Subscribe to MQTT Broker and Validate | broker.uri=127.0.0.1 | port=11883 | client.id=${client}
| | ... | topic=${topic} | message=${message}
| | Connect | 127.0.0.1 | 11883
| | Publish | ${topic} | test message with username and password | qos=1
| | Subscribe to MQTT Broker and Validate
| | ... | broker.uri=127.0.0.1 | port=11883 | client.id=${client} | topic=${topic} | message=test message with username and password
| | [Teardown] | Disconnect
| Publish to a broker that requires authentication with invalid password
| | [Tags] | auth
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test
| | Set username and password | authuser1 | invalidpwd
| | Run Keyword and expect error | The client disconnected unexpectedly
| | ... | Connect | 127.0.0.1 | 11883 | ${client}
| | [Teardown] | Disconnect
| Subscribe async, publish 1 message, listen for and validate it is received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Subscribe Async | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker | topic=${topic} | message=test message | qos=1
| | @{messages} | Listen and Get Messages | topic=${topic}
| | LOG | ${messages}
| | Length Should Be | ${messages} | 1
| | Should Be Equal As Strings | ${messages}[0] | test message
| | [Teardown] | Unsubscribe and Disconnect | ${topic}
| Subscribe async, publish several messages, listen for and validate they are received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Subscribe Async | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker | topic=${topic} | message=test message1 | qos=1
| | Publish to MQTT Broker | topic=${topic} | message=test message2 | qos=1
| | Publish to MQTT Broker | topic=${topic} | message=test message3 | qos=1
| | @{messages} | Listen and Get Messages | topic=${topic} | limit=0
| | LOG | ${messages}
| | Length Should Be | ${messages} | 3
| | Should Be Equal As Strings | ${messages}[0] | test message1
| | Should Be Equal As Strings | ${messages}[1] | test message2
| | Should Be Equal As Strings | ${messages}[2] | test message3
| | [Teardown] | Unsubscribe and Disconnect | ${topic}
| Subscribe async to multiple topics, publish several messages, listen for them and validate they are received
| | ${time} | Get Time | epoch
| | ${client1} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${client2} | Catenate | SEPARATOR=. | robot.mqtt | ${time+1}
| | ${topic1} | Set Variable | test/mqtt_test_sub1
| | ${topic2} | Set Variable | test/mqtt_test_sub2
| | Subscribe Async | client.id=${client1} | topic=${topic1}
| | Subscribe Async | client.id=${client2} | topic=${topic2}
| | Publish to MQTT Broker | topic=${topic2} | message=test message1 | qos=1
| | Publish to MQTT Broker | topic=${topic1} | message=test message2 | qos=1
| | Publish to MQTT Broker | topic=${topic2} | message=test message3 | qos=1
| | @{messages1} | Listen and Get Messages | topic=${topic1} | limit=0
| | @{messages2} | Listen and Get Messages | topic=${topic2} | limit=0
| | LOG | ${messages1}
| | LOG | ${messages2}
| | Length Should Be | ${messages1} | 1
| | Should Be Equal As Strings | ${messages1}[0] | test message2
| | Length Should Be | ${messages2} | 2
| | Should Be Equal As Strings | ${messages2}[0] | test message1
| | Should Be Equal As Strings | ${messages2}[1] | test message3
| | [Teardown] | Unsubscribe Multiple and Disconnect | ${topic1} | ${topic2}
| Listen immediately after Subscribe and validate message is received
| | ${time} | Get Time | epoch
| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
| | ${topic} | Set Variable | test/mqtt_test_sub
| | Subscribe and Get Messages | client.id=${client} | topic=${topic}
| | Publish to MQTT Broker and Disconnect | topic=${topic} | message=test message | qos=1
| | Subscribe Async | client.id=${client} | topic=${topic}
| | @{messages}= | Listen | topic=${topic} | limit=10 | timeout=5
| | Should Be Equal As Strings | ${messages}[0] | test message
| | [Teardown] | Unsubscribe and Disconnect | ${topic}

View File

@ -0,0 +1,35 @@
;***************************************************;
; Lilygo®Ttgo ESP32 with Lolin TFT 2.4" ;
; - T-Internet-Poe ESP32-WROOM ;
; - LAN8720A with POE ;
; - ili9341 TFT ;
; - xpt2606 touch controller ;
;***************************************************;
[env:ttgo_esp32-lolintft24]
platform = espressif32@^2.0.0
board = esp32dev
upload_protocol = espota ; Use ArduinoOTA after flashing over serial
upload_port = 10.4.70.37 ; 10.4.0.198 ; IP of the ESP
upload_flags =
--port=3232
;upload_port = COM9 ; To change the port, use platform_override.ini
monitor_port = COM9 ; To change the port, use platform_override.ini
board_build.partitions = esp32_partition_app1300k_spiffs1216k.csv ; default.csv
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
-D TFT_MISO=2
-D TFT_MOSI=15
-D TFT_SCLK=14
-D TFT_DC=4
-D TFT_CS=33
-D TFT_RST=12 ; RST
-D TFT_BCKL=16 ; None, configurable via web UI (e.g. 21)
-D TOUCH_CS=32 ; (can also be 22 or 16)
; -- Options ----------------------------------------
-D HASP_USE_TELNET=1
-D HASP_USE_ETHERNET=1
-D HASP_USE_WIFI=0

View File

@ -6,11 +6,12 @@
;***************************************************;
[env:d1mini32-lolintft24]
platform = espressif32@^1.12.0
platform = espressif32@^2.0.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 = esp32_partition_app1280k_spiffs1472k.csv
monitor_filters = esp32_exception_decoder
board_build.partitions = esp32_partition_app1300k_spiffs1216k.csv
build_flags =
${flags.esp32_flags}
@ -25,4 +26,5 @@ build_flags =
lib_ignore =
GxTFT
XPT2046_Touchscreen
XPT2046_Touchscreen
ESP32 BLE Arduino

View File

@ -5,7 +5,7 @@
;***************************************************;
[env:d132-unoshield]
platform = espressif32
platform = espressif32@^2.0.0
board = esp32dev
upload_port = COM4 ; To change the port, use platform_override.ini
monitor_port = COM4 ; To change the port, use platform_override.ini

View File

@ -5,7 +5,7 @@
;***************************************************;
[env:esp32dev-ili9488]
platform = espressif32
platform = espressif32@^2.0.0
board = esp32dev
upload_port = COM2 ; To change the port, use platform_override.ini
monitor_port = COM2 ; To change the port, use platform_override.ini

View File

@ -6,7 +6,7 @@
;***************************************************;
[env:esp32dev-mrb3511]
platform = espressif32
platform = espressif32@^2.0.0
board = esp32dev
upload_port = COM1 ; To change the port, use platform_override.ini
monitor_port = COM1 ; To change the port, use platform_override.ini

View File

@ -6,7 +6,7 @@
;***************************************************;
[env:esp32cam-st7796]
platform = espressif32
platform = espressif32@^2.0.0
board = esp32cam
; upload_port = COM18 ; To change the port, use platform_override.ini
; monitor_port = COM18 ; To change the port, use platform_override.ini

View File

@ -6,7 +6,7 @@
;***************************************************;
[env:nodemcu32s-raspi]
platform = espressif32
platform = espressif32@^2.0.0
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

View File

@ -6,7 +6,7 @@
;***************************************************;
[env:d1mini-lolintft24]
platform = espressif8266@^2.4.0 ;@2.3.2
platform = espressif8266@^2.6.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

View File

@ -5,7 +5,7 @@
;***************************************************;
[env:esp12e-st7735]
platform = espressif8266@^2.4.0 ;@2.3.2
platform = espressif8266@^2.6.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