Allow gpio PWM

This commit is contained in:
fvanroie 2021-01-23 01:32:52 +01:00
parent 6a29167c50
commit 7ca86b59bb
10 changed files with 555 additions and 384 deletions

View File

@ -4,6 +4,8 @@
#ifndef HASP_H #ifndef HASP_H
#define HASP_H #define HASP_H
#define NORMALIZE(a, b, c) map(a, b, c, 0, 0xFFFFU)
#include <Arduino.h> #include <Arduino.h>
#include "lvgl.h" #include "lvgl.h"
#include "hasp_conf.h" #include "hasp_conf.h"

View File

@ -260,16 +260,16 @@ lv_chart_series_t * my_chart_get_series(lv_obj_t * chart, uint8_t ser_num)
*/ */
void my_obj_set_value_str_txt(lv_obj_t * obj, uint8_t part, lv_state_t state, const char * text) void my_obj_set_value_str_txt(lv_obj_t * obj, uint8_t part, lv_state_t state, const char * text)
{ {
// Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
const void * value_str_p = lv_obj_get_style_value_str(obj, part); const void * value_str_p = lv_obj_get_style_value_str(obj, part);
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
if(text == NULL || text[0] == 0) { if(text == NULL || text[0] == 0) {
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
lv_obj_set_style_local_value_str(obj, part, state, NULL); lv_obj_set_style_local_value_str(obj, part, state, NULL);
lv_mem_free(value_str_p); lv_mem_free(value_str_p);
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
return; return;
} }
@ -280,15 +280,15 @@ void my_obj_set_value_str_txt(lv_obj_t * obj, uint8_t part, lv_state_t state, co
size_t len = strlen(text) + 1; size_t len = strlen(text) + 1;
/*Allocate space for the new text*/ /*Allocate space for the new text*/
// Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
value_str_p = (char *)lv_mem_alloc(len); value_str_p = (char *)lv_mem_alloc(len);
LV_ASSERT_MEM(value_str_p); LV_ASSERT_MEM(value_str_p);
if(value_str_p == NULL) return; if(value_str_p == NULL) return;
// Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
strncpy((char *)value_str_p, text, len); strncpy((char *)value_str_p, text, len);
lv_obj_set_style_local_value_str(obj, part, state, (char *)value_str_p); lv_obj_set_style_local_value_str(obj, part, state, (char *)value_str_p);
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
return; return;
} }
@ -306,10 +306,10 @@ void my_obj_set_value_str_txt(lv_obj_t * obj, uint8_t part, lv_state_t state, co
} else { } else {
/*Free the old text*/ /*Free the old text*/
if(value_str_p != NULL) { if(value_str_p != NULL) {
// Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
lv_mem_free(value_str_p); lv_mem_free(value_str_p);
value_str_p = NULL; value_str_p = NULL;
// Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
} }
/*Get the size of the text*/ /*Get the size of the text*/
@ -322,7 +322,7 @@ void my_obj_set_value_str_txt(lv_obj_t * obj, uint8_t part, lv_state_t state, co
lv_obj_set_style_local_value_str(obj, part, state, (char *)value_str_p); lv_obj_set_style_local_value_str(obj, part, state, (char *)value_str_p);
} }
// Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); // Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
} }
void my_btnmatrix_map_clear(lv_obj_t * obj) void my_btnmatrix_map_clear(lv_obj_t * obj)
@ -342,11 +342,11 @@ void my_btnmatrix_map_clear(lv_obj_t * obj)
Log.verbose(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, map_p_tmp); // label pointer array block Log.verbose(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, map_p_tmp); // label pointer array block
lv_btnmatrix_set_map(obj, btnmatrix_default_map); // reset to default btnmap pointer lv_btnmatrix_set_map(obj, btnmatrix_default_map); // reset to default btnmap pointer
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
lv_mem_free(*map_p_tmp); // free label buffer reserved as a contiguous block lv_mem_free(*map_p_tmp); // free label buffer reserved as a contiguous block
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
lv_mem_free(map_p_tmp); // free label pointer array block lv_mem_free(map_p_tmp); // free label pointer array block
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
} }
} }
@ -389,13 +389,13 @@ static void my_btnmatrix_map_create(lv_obj_t * obj, const char * payload)
memset(buffer_addr, 0, tot_len); // Important, last index needs to be 0 => empty string "" memset(buffer_addr, 0, tot_len); // Important, last index needs to be 0 => empty string ""
/* Point of no return, destroy & free the previous map */ /* Point of no return, destroy & free the previous map */
Log.verbose(TAG_ATTR, "%s %d map addr: %x", __FILE__, __LINE__, map_data_str); Log.verbose(TAG_ATTR, F("%s %d map addr: %x"), __FILE__, __LINE__, map_data_str);
my_btnmatrix_map_clear(obj); // Free previous map my_btnmatrix_map_clear(obj); // Free previous map
// Fill buffer // Fill buffer
size_t index = 0; size_t index = 0;
size_t pos = 0; size_t pos = 0;
Log.verbose(TAG_ATTR, "%s %d lbl addr: %x", __FILE__, __LINE__, buffer_addr); Log.verbose(TAG_ATTR, F("%s %d lbl addr: %x"), __FILE__, __LINE__, buffer_addr);
for(JsonVariant btn : arr) { for(JsonVariant btn : arr) {
size_t len = btn.as<String>().length() + 1; size_t len = btn.as<String>().length() + 1;
Log.verbose(TAG_ATTR, F(" * Adding button: %s (%d bytes) %x"), btn.as<String>().c_str(), len, Log.verbose(TAG_ATTR, F(" * Adding button: %s (%d bytes) %x"), btn.as<String>().c_str(), len,
@ -406,9 +406,9 @@ static void my_btnmatrix_map_create(lv_obj_t * obj, const char * payload)
} }
map_data_str[index] = buffer_addr + pos; // save pointer to the last \0 byte map_data_str[index] = buffer_addr + pos; // save pointer to the last \0 byte
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
lv_btnmatrix_set_map(obj, map_data_str); lv_btnmatrix_set_map(obj, map_data_str);
Log.verbose(TAG_ATTR, "%s %d", __FILE__, __LINE__); Log.verbose(TAG_ATTR, F("%s %d"), __FILE__, __LINE__);
} }
void line_clear_points(lv_obj_t * obj) void line_clear_points(lv_obj_t * obj)
@ -497,140 +497,155 @@ static bool haspPayloadToColor(const char * payload, lv_color_t & color)
uint8_t G8 = (G6 * 259 + 33) >> 6; uint8_t G8 = (G6 * 259 + 33) >> 6;
uint8_t B8 = (B5 * 527 + 23) >> 6; uint8_t B8 = (B5 * 527 + 23) >> 6;
color = lv_color_make(R8, G8, B8); color = lv_color_make(R8, G8, B8);
} else { } else {
/* Named Color Scheme*/ /* Named Color Scheme*/
switch(hasp_util_get_sdbm(payload)) { // switch(hasp_util_get_sdbm(payload)) {
case ATTR_RED: // case ATTR_RED:
color = lv_color_make(0xFF, 0x00, 0x00); // color = lv_color_make(0xFF, 0x00, 0x00);
break; // break;
case ATTR_TAN: // case ATTR_TAN:
color = lv_color_make(0xD2, 0xB4, 0x8C); // color = lv_color_make(0xD2, 0xB4, 0x8C);
break; // break;
case ATTR_BLUE: // case ATTR_BLUE:
color = lv_color_make(0x00, 0x00, 0xFF); // color = lv_color_make(0x00, 0x00, 0xFF);
break; // break;
case ATTR_AQUA: // case ATTR_AQUA:
case ATTR_CYAN: // case ATTR_CYAN:
color = lv_color_make(0x00, 0xFF, 0xFF); // color = lv_color_make(0x00, 0xFF, 0xFF);
break; // break;
case ATTR_GOLD: // case ATTR_GOLD:
color = lv_color_make(0xFF, 0xD7, 0x00); // color = lv_color_make(0xFF, 0xD7, 0x00);
break; // break;
case ATTR_GRAY: // case ATTR_GRAY:
case ATTR_GREY: // case ATTR_GREY:
color = lv_color_make(0x80, 0x80, 0x80); // color = lv_color_make(0x80, 0x80, 0x80);
break; // break;
case ATTR_LIME: // case ATTR_LIME:
color = lv_color_make(0x00, 0xFF, 0x00); // color = lv_color_make(0x00, 0xFF, 0x00);
break; // break;
case ATTR_NAVY: // case ATTR_NAVY:
color = lv_color_make(0x00, 0x00, 0x80); // color = lv_color_make(0x00, 0x00, 0x80);
break; // break;
case ATTR_PERU: // case ATTR_PERU:
color = lv_color_make(0xCD, 0x85, 0x3F); // color = lv_color_make(0xCD, 0x85, 0x3F);
break; // break;
case ATTR_PINK: // case ATTR_PINK:
color = lv_color_make(0xFF, 0xC0, 0xCB); // color = lv_color_make(0xFF, 0xC0, 0xCB);
break; // break;
case ATTR_PLUM: // case ATTR_PLUM:
color = lv_color_make(0xDD, 0xA0, 0xDD); // color = lv_color_make(0xDD, 0xA0, 0xDD);
break; // break;
case ATTR_SNOW: // case ATTR_SNOW:
color = lv_color_make(0xFF, 0xFA, 0xFA); // color = lv_color_make(0xFF, 0xFA, 0xFA);
break; // break;
case ATTR_TEAL: // case ATTR_TEAL:
color = lv_color_make(0x00, 0x80, 0x80); // color = lv_color_make(0x00, 0x80, 0x80);
break; // break;
case ATTR_AZURE: // case ATTR_AZURE:
color = lv_color_make(0xF0, 0xFF, 0xFF); // color = lv_color_make(0xF0, 0xFF, 0xFF);
break; // break;
case ATTR_BEIGE: // case ATTR_BEIGE:
color = lv_color_make(0xF5, 0xF5, 0xDC); // color = lv_color_make(0xF5, 0xF5, 0xDC);
break; // break;
case ATTR_BLACK: // case ATTR_BLACK:
color = lv_color_make(0x00, 0x00, 0x00); // color = lv_color_make(0x00, 0x00, 0x00);
break; // break;
case ATTR_BLUSH: // case ATTR_BLUSH:
color = lv_color_make(0xB0, 0x00, 0x00); // color = lv_color_make(0xB0, 0x00, 0x00);
break; // break;
case ATTR_BROWN: // case ATTR_BROWN:
color = lv_color_make(0xA5, 0x2A, 0x2A); // color = lv_color_make(0xA5, 0x2A, 0x2A);
break; // break;
case ATTR_CORAL: // case ATTR_CORAL:
color = lv_color_make(0xFF, 0x7F, 0x50); // color = lv_color_make(0xFF, 0x7F, 0x50);
break; // break;
case ATTR_GREEN: // case ATTR_GREEN:
color = lv_color_make(0x00, 0x80, 0x00); // color = lv_color_make(0x00, 0x80, 0x00);
break; // break;
case ATTR_IVORY: // case ATTR_IVORY:
color = lv_color_make(0xFF, 0xFF, 0xF0); // color = lv_color_make(0xFF, 0xFF, 0xF0);
break; // break;
case ATTR_KHAKI: // case ATTR_KHAKI:
color = lv_color_make(0xF0, 0xE6, 0x8C); // color = lv_color_make(0xF0, 0xE6, 0x8C);
break; // break;
case ATTR_LINEN: // case ATTR_LINEN:
color = lv_color_make(0xFA, 0xF0, 0xE6); // color = lv_color_make(0xFA, 0xF0, 0xE6);
break; // break;
case ATTR_OLIVE: // case ATTR_OLIVE:
color = lv_color_make(0x80, 0x80, 0x00); // color = lv_color_make(0x80, 0x80, 0x00);
break; // break;
case ATTR_WHEAT: // case ATTR_WHEAT:
color = lv_color_make(0xF5, 0xDE, 0xB3); // color = lv_color_make(0xF5, 0xDE, 0xB3);
break; // break;
case ATTR_WHITE: // case ATTR_WHITE:
color = lv_color_make(0xFF, 0xFF, 0xFF); // color = lv_color_make(0xFF, 0xFF, 0xFF);
break; // break;
case ATTR_BISQUE: // case ATTR_BISQUE:
color = lv_color_make(0xFF, 0xE4, 0xC4); // color = lv_color_make(0xFF, 0xE4, 0xC4);
break; // break;
case ATTR_INDIGO: // case ATTR_INDIGO:
color = lv_color_make(0x4B, 0x00, 0x82); // color = lv_color_make(0x4B, 0x00, 0x82);
break; // break;
case ATTR_MAROON: // case ATTR_MAROON:
color = lv_color_make(0x80, 0x00, 0x00); // color = lv_color_make(0x80, 0x00, 0x00);
break; // break;
case ATTR_ORANGE: // case ATTR_ORANGE:
color = lv_color_make(0xFF, 0xA5, 0x00); // color = lv_color_make(0xFF, 0xA5, 0x00);
break; // break;
case ATTR_ORCHID: // case ATTR_ORCHID:
color = lv_color_make(0xDA, 0x70, 0xD6); // color = lv_color_make(0xDA, 0x70, 0xD6);
break; // break;
case ATTR_PURPLE: // case ATTR_PURPLE:
color = lv_color_make(0x80, 0x00, 0x80); // color = lv_color_make(0x80, 0x00, 0x80);
break; // break;
case ATTR_SALMON: // case ATTR_SALMON:
color = lv_color_make(0xFA, 0x80, 0x72); // color = lv_color_make(0xFA, 0x80, 0x72);
break; // break;
case ATTR_SIENNA: // case ATTR_SIENNA:
color = lv_color_make(0xA0, 0x52, 0x2D); // color = lv_color_make(0xA0, 0x52, 0x2D);
break; // break;
case ATTR_SILVER: // case ATTR_SILVER:
color = lv_color_make(0xC0, 0xC0, 0xC0); // color = lv_color_make(0xC0, 0xC0, 0xC0);
break; // break;
case ATTR_TOMATO: // case ATTR_TOMATO:
color = lv_color_make(0xFF, 0x63, 0x47); // color = lv_color_make(0xFF, 0x63, 0x47);
break; // break;
case ATTR_VIOLET: // case ATTR_VIOLET:
color = lv_color_make(0xEE, 0x82, 0xEE); // color = lv_color_make(0xEE, 0x82, 0xEE);
break; // break;
case ATTR_YELLOW: // case ATTR_YELLOW:
color = lv_color_make(0xFF, 0xFF, 0x00); // color = lv_color_make(0xFF, 0xFF, 0x00);
break; // break;
case ATTR_FUCHSIA: // case ATTR_FUCHSIA:
case ATTR_MAGENTA: // case ATTR_MAGENTA:
color = lv_color_make(0xFF, 0x00, 0xFF); // color = lv_color_make(0xFF, 0x00, 0xFF);
break; // break;
default: // default:
/* Unknown color name */ // /* Unknown color name */
Log.warning(TAG_ATTR, F("Invalid color %s"), payload); // Log.warning(TAG_ATTR, F("Invalid color %s"), payload);
return false; // return false;
// }
// }
size_t numColors = sizeof(haspNamedColors) / sizeof(haspNamedColors[0]);
uint16_t sdbm = hasp_util_get_sdbm(payload);
for(size_t i = 0; i < numColors; i++) {
if(sdbm == (uint16_t)pgm_read_word_near(&(haspNamedColors[i].hash))) {
uint8_t r = (uint16_t)pgm_read_byte_near(&(haspNamedColors[i].r));
uint8_t g = (uint16_t)pgm_read_byte_near(&(haspNamedColors[i].g));
uint8_t b = (uint16_t)pgm_read_byte_near(&(haspNamedColors[i].b));
color = lv_color_make(r, g, b);
return true; /* Color found */
} }
} }
return false; /* Color not found */
}
/* Unknown color scheme */ return true; /* Color found */
return true;
} }
static lv_font_t * haspPayloadToFont(const char * payload) static lv_font_t * haspPayloadToFont(const char * payload)
@ -1034,7 +1049,7 @@ static void hasp_local_style_attr(lv_obj_t * obj, const char * attr_p, uint16_t
case ATTR_TEXT_FONT: { case ATTR_TEXT_FONT: {
lv_font_t * font = haspPayloadToFont(payload); lv_font_t * font = haspPayloadToFont(payload);
if(font) { if(font) {
uint8_t count; uint8_t count = 3;
if(check_obj_type(obj, LV_HASP_ROLLER)) count = my_roller_get_visible_row_count(obj); if(check_obj_type(obj, LV_HASP_ROLLER)) count = my_roller_get_visible_row_count(obj);
lv_obj_set_style_local_text_font(obj, part, state, font); lv_obj_set_style_local_text_font(obj, part, state, font);
if(check_obj_type(obj, LV_HASP_ROLLER)) lv_roller_set_visible_row_count(obj, count); if(check_obj_type(obj, LV_HASP_ROLLER)) lv_roller_set_visible_row_count(obj, count);
@ -1390,100 +1405,59 @@ static void hasp_process_obj_attribute_txt(lv_obj_t * obj, const char * attr, co
Log.warning(TAG_ATTR, F("Unknown property %s"), attr); Log.warning(TAG_ATTR, F("Unknown property %s"), attr);
} }
static void hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, const char * payload, bool update) bool hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, const char * payload, bool update)
{ {
int16_t intval = atoi(payload); int16_t intval = atoi(payload);
uint16_t val = atoi(payload);
/* Attributes depending on objecttype */ if(check_obj_type(obj, LV_HASP_BUTTON)) {
// lv_obj_type_t list; if(lv_btn_get_checkable(obj)) {
// lv_obj_get_type(obj, &list);
// const char * objtype = list.type[0];
if(check_obj_type(obj, LV_HASP_BUTTON) && lv_btn_get_checkable(obj)) {
if(update) { if(update) {
lv_btn_state_t state; if(intval)
switch(val) { lv_obj_add_state(obj, LV_STATE_CHECKED);
case 0: else
state = LV_BTN_STATE_RELEASED; lv_obj_clear_state(obj, LV_STATE_CHECKED);
break;
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 { } else {
lv_btn_state_t state = lv_btn_get_state(obj); hasp_out_int(obj, attr, lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_CHECKED);
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);
} }
} else {
return false; // not checkable
} }
} } else if(check_obj_type(obj, LV_HASP_CHECKBOX)) {
update ? lv_checkbox_set_checked(obj, hasp_util_is_true(payload))
if(check_obj_type(obj, LV_HASP_CHECKBOX)) {
return update ? lv_checkbox_set_checked(obj, hasp_util_is_true(payload))
: hasp_out_int(obj, attr, lv_checkbox_is_checked(obj)); : hasp_out_int(obj, attr, lv_checkbox_is_checked(obj));
} } else if(check_obj_type(obj, LV_HASP_SWITCH)) {
if(check_obj_type(obj, LV_HASP_SWITCH)) { if(update)
if(update) { hasp_util_is_true(payload) ? lv_switch_on(obj, LV_ANIM_ON) : lv_switch_off(obj, LV_ANIM_ON);
return hasp_util_is_true(payload) ? lv_switch_on(obj, LV_ANIM_ON) : lv_switch_off(obj, LV_ANIM_ON); else
} else { hasp_out_int(obj, attr, lv_switch_get_state(obj));
return hasp_out_int(obj, attr, lv_switch_get_state(obj));
}
} else if(check_obj_type(obj, LV_HASP_DDLIST)) { } else if(check_obj_type(obj, LV_HASP_DDLIST)) {
lv_dropdown_set_selected(obj, val); lv_dropdown_set_selected(obj, (uint16_t)intval);
return;
} else if(check_obj_type(obj, LV_HASP_LMETER)) { } else if(check_obj_type(obj, LV_HASP_LMETER)) {
return update ? lv_linemeter_set_value(obj, intval) : hasp_out_int(obj, attr, lv_linemeter_get_value(obj)); update ? lv_linemeter_set_value(obj, intval) : hasp_out_int(obj, attr, lv_linemeter_get_value(obj));
} else if(check_obj_type(obj, LV_HASP_SLIDER)) { } else if(check_obj_type(obj, LV_HASP_SLIDER)) {
return update ? lv_slider_set_value(obj, intval, LV_ANIM_ON) update ? lv_slider_set_value(obj, intval, LV_ANIM_ON) : hasp_out_int(obj, attr, lv_slider_get_value(obj));
: hasp_out_int(obj, attr, lv_slider_get_value(obj));
} else if(check_obj_type(obj, LV_HASP_LED)) { } else if(check_obj_type(obj, LV_HASP_LED)) {
return update ? lv_led_set_bright(obj, (uint8_t)val) : hasp_out_int(obj, attr, lv_led_get_bright(obj)); update ? lv_led_set_bright(obj, (uint8_t)intval) : hasp_out_int(obj, attr, lv_led_get_bright(obj));
} else if(check_obj_type(obj, LV_HASP_ARC)) { } else if(check_obj_type(obj, LV_HASP_ARC)) {
return update ? lv_arc_set_value(obj, intval) : hasp_out_int(obj, attr, lv_arc_get_value(obj)); update ? lv_arc_set_value(obj, intval) : hasp_out_int(obj, attr, lv_arc_get_value(obj));
} else if(check_obj_type(obj, LV_HASP_GAUGE)) { } else if(check_obj_type(obj, LV_HASP_GAUGE)) {
return update ? lv_gauge_set_value(obj, 0, intval) : hasp_out_int(obj, attr, lv_gauge_get_value(obj, 0)); update ? lv_gauge_set_value(obj, 0, intval) : hasp_out_int(obj, attr, lv_gauge_get_value(obj, 0));
} else if(check_obj_type(obj, LV_HASP_ROLLER)) { } else if(check_obj_type(obj, LV_HASP_ROLLER)) {
lv_roller_set_selected(obj, val, LV_ANIM_ON); lv_roller_set_selected(obj, (uint16_t)intval, LV_ANIM_ON);
return;
} else if(check_obj_type(obj, LV_HASP_BAR)) { } else if(check_obj_type(obj, LV_HASP_BAR)) {
return update ? lv_bar_set_value(obj, intval, LV_ANIM_ON) : hasp_out_int(obj, attr, lv_bar_get_value(obj)); 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(obj, LV_HASP_CPICKER)) { } else if(check_obj_type(obj, LV_HASP_CPICKER)) {
if(update) { if(update) {
lv_color_t color; lv_color_t color;
if(!haspPayloadToColor(payload, color)) return; if(haspPayloadToColor(payload, color)) lv_cpicker_set_color(obj, color);
lv_cpicker_set_color(obj, color);
} else { } else {
hasp_out_color(obj, attr, lv_cpicker_get_color(obj)); hasp_out_color(obj, attr, lv_cpicker_get_color(obj));
} }
return; } else {
return false;
} }
Log.warning(TAG_ATTR, F("Unknown property %s"), attr); return true;
} }
static void hasp_process_obj_attribute_range(lv_obj_t * obj, const char * attr, const char * payload, bool update, static void hasp_process_obj_attribute_range(lv_obj_t * obj, const char * attr, const char * payload, bool update,
@ -1639,7 +1613,7 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
break; // attribute_found break; // attribute_found
case ATTR_VAL: case ATTR_VAL:
hasp_process_obj_attribute_val(obj, attr, payload, update); if(!hasp_process_obj_attribute_val(obj, attr, payload, update)) goto attribute_not_found;
break; // attribute_found break; // attribute_found
case ATTR_MIN: case ATTR_MIN:
@ -1832,5 +1806,5 @@ attribute_found:
return; return;
attribute_not_found: attribute_not_found:
Log.verbose(TAG_ATTR, F("%s (%d)"), attr_p, attr_hash); Log.warning(TAG_ATTR, F("Unknown property %s (%d)"), attr_p, attr_hash);
} }

View File

@ -25,6 +25,7 @@ void my_btnmatrix_map_clear(lv_obj_t * obj);
void line_clear_points(lv_obj_t * obj); void line_clear_points(lv_obj_t * obj);
void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char * payload, bool update); void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char * payload, bool update);
bool hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, const char * payload, bool update);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
@ -342,4 +343,28 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t)
#define ATTR_FUCHSIA 5463 #define ATTR_FUCHSIA 5463
#define ATTR_MAGENTA 49385 #define ATTR_MAGENTA 49385
struct hasp_color_t
{
uint16_t hash;
uint8_t r, g, b;
};
/* Named COLOR lookup table */
const hasp_color_t haspNamedColors[] PROGMEM = {
{ATTR_RED, 0xFF, 0x00, 0x00}, {ATTR_TAN, 0xD2, 0xB4, 0x8C}, {ATTR_AQUA, 0x00, 0xFF, 0xFF},
{ATTR_BLUE, 0x00, 0x00, 0xFF}, {ATTR_CYAN, 0x00, 0xFF, 0xFF}, {ATTR_GOLD, 0xFF, 0xD7, 0x00},
{ATTR_GRAY, 0x80, 0x80, 0x80}, {ATTR_GREY, 0x80, 0x80, 0x80}, {ATTR_LIME, 0x00, 0xFF, 0x00},
{ATTR_NAVY, 0x00, 0x00, 0x80}, {ATTR_PERU, 0xCD, 0x85, 0x3F}, {ATTR_PINK, 0xFF, 0xC0, 0xCB},
{ATTR_PLUM, 0xDD, 0xA0, 0xDD}, {ATTR_SNOW, 0xFF, 0xFA, 0xFA}, {ATTR_TEAL, 0x00, 0x80, 0x80},
{ATTR_AZURE, 0xF0, 0xFF, 0xFF}, {ATTR_BEIGE, 0xF5, 0xF5, 0xDC}, {ATTR_BLACK, 0x00, 0x00, 0x00},
{ATTR_BLUSH, 0xB0, 0x00, 0x00}, {ATTR_BROWN, 0xA5, 0x2A, 0x2A}, {ATTR_CORAL, 0xFF, 0x7F, 0x50},
{ATTR_GREEN, 0x00, 0x80, 0x00}, {ATTR_IVORY, 0xFF, 0xFF, 0xF0}, {ATTR_KHAKI, 0xF0, 0xE6, 0x8C},
{ATTR_LINEN, 0xFA, 0xF0, 0xE6}, {ATTR_OLIVE, 0x80, 0x80, 0x00}, {ATTR_WHEAT, 0xF5, 0xDE, 0xB3},
{ATTR_WHITE, 0xFF, 0xFF, 0xFF}, {ATTR_BISQUE, 0xFF, 0xE4, 0xC4}, {ATTR_INDIGO, 0x4B, 0x00, 0x82},
{ATTR_MAROON, 0x80, 0x00, 0x00}, {ATTR_ORANGE, 0xFF, 0xA5, 0x00}, {ATTR_ORCHID, 0xDA, 0x70, 0xD6},
{ATTR_PURPLE, 0x80, 0x00, 0x80}, {ATTR_SALMON, 0xFA, 0x80, 0x72}, {ATTR_SIENNA, 0xA0, 0x52, 0x2D},
{ATTR_SILVER, 0xC0, 0xC0, 0xC0}, {ATTR_TOMATO, 0xFF, 0x63, 0x47}, {ATTR_VIOLET, 0xEE, 0x82, 0xEE},
{ATTR_YELLOW, 0xFF, 0xFF, 0x00}, {ATTR_FUCHSIA, 0xFF, 0x00, 0xFF}, {ATTR_MAGENTA, 0xFF, 0x00, 0xFF},
};
#endif #endif

View File

@ -37,7 +37,7 @@ uint8_t nCommands = 0;
haspCommand_t commands[16]; haspCommand_t commands[16];
static void dispatch_config(const char * topic, const char * payload); static void dispatch_config(const char * topic, const char * payload);
static void dispatch_group_state(uint8_t groupid, uint8_t eventid, lv_obj_t * obj); // void dispatch_group_value(uint8_t groupid, int16_t state, lv_obj_t * obj);
static inline void dispatch_state_msg(const __FlashStringHelper * subtopic, const char * payload); static inline void dispatch_state_msg(const __FlashStringHelper * subtopic, const char * payload);
void dispatch_screenshot(const char *, const char * filename) void dispatch_screenshot(const char *, const char * filename)
@ -101,6 +101,18 @@ inline void dispatch_process_button_attribute(String strTopic, const char * payl
if(pageid >= 0 && pageid <= 255 && objid >= 0 && objid <= 255) { if(pageid >= 0 && pageid <= 255 && objid >= 0 && objid <= 255) {
hasp_process_attribute((uint8_t)pageid, (uint8_t)objid, strAttr.c_str(), payload); hasp_process_attribute((uint8_t)pageid, (uint8_t)objid, strAttr.c_str(), payload);
} // valid page } // valid page
} else {
unsigned int pageid, objid;
const char * topic_p = strTopic.c_str();
if(sscanf(topic_p, "p%ub%u.", &pageid, &objid) == 2) { // Literal String
size_t offset = 0;
while(topic_p[offset++] != '.') {
}
hasp_process_attribute((uint8_t)pageid, (uint8_t)objid, topic_p + offset, payload);
}
} }
} }
@ -121,8 +133,8 @@ void dispatch_command(const char * topic, const char * payload)
/* =============================== Not standard payload commands ===================================== */ /* =============================== Not standard payload commands ===================================== */
if(strlen(topic) == 7 && topic == strstr_P(topic, PSTR("output"))) { if(strlen(topic) == 7 && topic == strstr_P(topic, PSTR("output"))) {
dispatch_group_state(atoi(topic + 6), hasp_util_is_true(payload) ? HASP_EVENT_ON : HASP_EVENT_OFF, int16_t state = atoi(payload);
NULL); // + 6 => trim 'output' from the topic dispatch_normalized_group_value(atoi(topic + 6), state, NULL); // + 6 => trim 'output' from the topic
// } else if(strcasecmp_P(topic, PSTR("screenshot")) == 0) { // } else if(strcasecmp_P(topic, PSTR("screenshot")) == 0) {
// guiTakeScreenshot("/screenshot.bmp"); // Literal String // guiTakeScreenshot("/screenshot.bmp"); // Literal String
@ -243,8 +255,20 @@ void dispatch_output_idle_state(uint8_t state)
dispatch_state_msg(F("idle"), payload); dispatch_state_msg(F("idle"), payload);
} }
void dispatch_output_group_state(uint8_t groupid, uint16_t state)
{
char payload[64];
char number[16]; // Return the current state
itoa(state, number, DEC);
snprintf_P(payload, sizeof(payload), PSTR("{\"group\":%d,\"state\":\"%s\"}"), groupid, number);
dispatch_state_msg(F("output"), payload);
}
void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data) void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
{ {
if(!attribute || !data) return;
char topic[12]; char topic[12];
char payload[32 + strlen(data) + strlen(attribute)]; char payload[32 + strlen(data) + strlen(attribute)];
// snprintf_P(payload, sizeof(payload), PSTR("{\"page\":%u,\"id\":%u,\"%s\":\"%s\"}"), pageid, btnid, attribute, // snprintf_P(payload, sizeof(payload), PSTR("{\"page\":%u,\"id\":%u,\"%s\":\"%s\"}"), pageid, btnid, attribute,
@ -399,7 +423,7 @@ static void dispatch_get_event_name(uint8_t eventid, char * buffer, size_t size)
} }
#if HASP_USE_GPIO > 0 #if HASP_USE_GPIO > 0
void dispatch_gpio_event(uint8_t pin, uint8_t group, uint8_t eventid) void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid)
{ {
char payload[64]; char payload[64];
char event[8]; char event[8];
@ -411,7 +435,7 @@ void dispatch_gpio_event(uint8_t pin, uint8_t group, uint8_t eventid)
#endif #endif
// update outputstates // update outputstates
dispatch_group_state(group, dispatch_get_event_state(eventid), NULL); // dispatch_group_onoff(group, dispatch_get_event_state(eventid), NULL);
} }
#endif #endif
@ -428,9 +452,16 @@ void dispatch_object_event(lv_obj_t * obj, uint8_t eventid)
dispatch_send_obj_attribute_str(pageid, objid, topic, payload); dispatch_send_obj_attribute_str(pageid, objid, topic, payload);
} }
if(obj->user_data.groupid > 0) { // dispatch_group_onoff(obj->user_data.groupid, dispatch_get_event_state(eventid), obj);
dispatch_group_state(obj->user_data.groupid, eventid, obj); }
}
void dispatch_object_value_changed(lv_obj_t * obj, int16_t state)
{
char topic[4];
hasp_update_sleep_state(); // wakeup?
snprintf_P(topic, sizeof(topic), PSTR("val"));
hasp_send_obj_attribute_int(obj, topic, state);
} }
/********************************************** Output States ******************************************/ /********************************************** Output States ******************************************/
@ -448,21 +479,39 @@ static inline void dispatch_state_msg(const __FlashStringHelper * subtopic, cons
#endif #endif
} }
void dispatch_group_state(uint8_t groupid, uint8_t eventid, lv_obj_t * obj) // void dispatch_group_onoff(uint8_t groupid, uint16_t eventid, lv_obj_t * obj)
// {
// if((eventid == HASP_EVENT_LONG) || (eventid == HASP_EVENT_HOLD)) return; // don't send repeat events
// if(groupid >= 0) {
// bool state = dispatch_get_event_state(eventid);
// gpio_set_group_onoff(groupid, state);
// object_set_group_state(groupid, eventid, obj);
// }
// char payload[8];
// dispatch_get_event_name(eventid, payload, sizeof(payload));
// // dispatch_output_group_state(groupid, payload);
// }
// void dispatch_group_value(uint8_t groupid, int16_t state, lv_obj_t * obj)
// {
// if(groupid >= 0) {
// gpio_set_group_value(groupid, state);
// object_set_group_state(groupid, state, obj);
// }
// char payload[8];
// // dispatch_output_group_state(groupid, payload);
// }
void dispatch_normalized_group_value(uint8_t groupid, uint16_t value, lv_obj_t * obj)
{ {
if((eventid == HASP_EVENT_LONG) || (eventid == HASP_EVENT_HOLD)) return; // don't send repeat events if(groupid > 0) {
Log.verbose(TAG_MSGR, F("GROUP %d value %d"), groupid, value);
if(groupid >= 0) { gpio_set_normalized_group_value(groupid, value);
gpio_set_group_state(groupid, eventid); // object_set_group_state(groupid, value, obj);
object_set_group_state(groupid, eventid, obj);
} }
char payload[64];
char state[4]; // Return the current state
memcpy_P(state, dispatch_get_event_state(eventid) ? PSTR("ON") : PSTR("OFF"), sizeof(state));
snprintf_P(payload, sizeof(payload), PSTR("{\"group\":%d,\"state\":\"%s\"}"), groupid, state);
dispatch_state_msg(F("output"), payload);
} }
/********************************************** Native Commands ****************************************/ /********************************************** Native Commands ****************************************/

View File

@ -47,9 +47,12 @@ void dispatch_output_idle_state(uint8_t state);
void dispatch_output_statusupdate(const char *, const char *); void dispatch_output_statusupdate(const char *, const char *);
void dispatch_output_current_page(); void dispatch_output_current_page();
void dispatch_gpio_event(uint8_t pin, uint8_t group, uint8_t eventid); void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid);
void dispatch_object_event(lv_obj_t * obj, uint8_t eventid); void dispatch_object_event(lv_obj_t * obj, uint8_t eventid);
bool dispatch_get_event_state(uint8_t eventid); bool dispatch_get_event_state(uint8_t eventid);
void dispatch_object_value_changed(lv_obj_t * obj, int16_t state);
void dispatch_normalized_group_value(uint8_t groupid, uint16_t value, lv_obj_t * obj);
void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute,
const char * data); const char * data);

View File

@ -48,7 +48,6 @@ lv_obj_t * hasp_find_obj_from_parent_id(lv_obj_t * parent, uint8_t objid)
/* check tabs */ /* check tabs */
if(check_obj_type(child, LV_HASP_TABVIEW)) { if(check_obj_type(child, LV_HASP_TABVIEW)) {
//#if LVGL_VERSION_MAJOR == 7
uint16_t tabcount = lv_tabview_get_tab_count(child); uint16_t tabcount = lv_tabview_get_tab_count(child);
for(uint16_t i = 0; i < tabcount; i++) { for(uint16_t i = 0; i < tabcount; i++) {
lv_obj_t * tab = lv_tabview_get_tab(child, i); lv_obj_t * tab = lv_tabview_get_tab(child, i);
@ -59,7 +58,6 @@ lv_obj_t * hasp_find_obj_from_parent_id(lv_obj_t * parent, uint8_t objid)
grandchild = hasp_find_obj_from_parent_id(tab, objid); grandchild = hasp_find_obj_from_parent_id(tab, objid);
if(grandchild) return grandchild; /* grandchild found, return it */ if(grandchild) return grandchild; /* grandchild found, return it */
} }
//#endif
} }
/* try next sibling */ /* try next sibling */
@ -231,6 +229,7 @@ void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_co
{ {
char buffer[40]; // "#ffffff","r":"255","g":"255","b":"255" char buffer[40]; // "#ffffff","r":"255","g":"255","b":"255"
lv_color32_t c32; lv_color32_t c32;
c32.full = lv_color_to32(color); c32.full = lv_color_to32(color);
snprintf_P(buffer, sizeof(buffer), PSTR("#%02x%02x%02x\",\"r\":\"%d\",\"g\":\"%d\",\"b\":\"%d"), c32.ch.red, snprintf_P(buffer, sizeof(buffer), PSTR("#%02x%02x%02x\",\"r\":\"%d\",\"g\":\"%d\",\"b\":\"%d"), c32.ch.red,
c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue);
@ -239,31 +238,32 @@ void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_co
// ##################### Value Senders ######################################################## // ##################### Value Senders ########################################################
static void hasp_send_obj_attribute_P(lv_obj_t * obj, const char * attr, const char * data) // static void hasp_send_obj_attribute_P(lv_obj_t * obj, const char * attr, const char * data)
{ // {
char * buffer; // char * buffer;
buffer = (char *)malloc(strlen_P(attr) + 1); // buffer = (char *)malloc(strlen_P(attr) + 1);
strcpy_P(buffer, attr); // strcpy_P(buffer, attr);
hasp_send_obj_attribute_str(obj, buffer, data); // hasp_send_obj_attribute_str(obj, buffer, data);
free(buffer); // free(buffer);
} // }
static inline void hasp_send_obj_attribute_val(lv_obj_t * obj, int32_t val) // static inline void hasp_obj_value_changed(lv_obj_t * obj, int32_t val)
{ // {
char data[32]; // dispatch_object_value_changed(obj, val);
itoa(val, data, DEC); // char data[32];
hasp_send_obj_attribute_P(obj, PSTR("val"), data); // itoa(val, data, DEC);
} // hasp_send_obj_attribute_P(obj, PSTR("val"), data);
//}
static inline void hasp_send_obj_attribute_event(lv_obj_t * obj, const char * event) // static inline void hasp_send_obj_attribute_event(lv_obj_t * obj, const char * event)
{ // {
hasp_send_obj_attribute_P(obj, PSTR("event"), event); // hasp_send_obj_attribute_P(obj, PSTR("event"), event);
} // }
static inline void hasp_send_obj_attribute_txt(lv_obj_t * obj, const char * txt) // static inline void hasp_send_obj_attribute_txt(lv_obj_t * obj, const char * txt)
{ // {
hasp_send_obj_attribute_P(obj, PSTR("txt"), txt); // hasp_send_obj_attribute_P(obj, PSTR("txt"), txt);
} // }
// ##################### Event Handlers ######################################################## // ##################### Event Handlers ########################################################
@ -272,7 +272,7 @@ static inline void hasp_send_obj_attribute_txt(lv_obj_t * obj, const char * txt)
* @param obj pointer to a button object * @param obj pointer to a button object
* @param event type of event that occured * @param event type of event that occured
*/ */
void IRAM_ATTR generic_event_handler(lv_obj_t * obj, lv_event_t event) void generic_event_handler(lv_obj_t * obj, lv_event_t event)
{ {
uint8_t eventid; uint8_t eventid;
@ -333,6 +333,7 @@ void IRAM_ATTR generic_event_handler(lv_obj_t * obj, lv_event_t event)
hasp_update_sleep_state(); // wakeup? hasp_update_sleep_state(); // wakeup?
dispatch_object_event(obj, eventid); // send object event dispatch_object_event(obj, eventid); // send object event
dispatch_normalized_group_value(obj->user_data.groupid, NORMALIZE(dispatch_get_event_state(eventid), 0, 1), obj);
} }
/** /**
@ -349,31 +350,39 @@ void wakeup_event_handler(lv_obj_t * obj, lv_event_t event)
} }
/** /**
* Called when a toggle button is clicked * Called when a object state is toggled on/off
* @param obj pointer to a button
* @param event type of event that occured
*/
void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
hasp_update_sleep_state(); // wakeup?
hasp_send_obj_attribute_val(obj, lv_checkbox_is_checked(obj));
} else if(event == LV_EVENT_DELETE) {
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
hasp_object_delete(obj);
}
}
/**
* Called when a switch is toggled
* @param obj pointer to a switch object * @param obj pointer to a switch object
* @param event type of event that occured * @param event type of event that occured
*/ */
static void switch_event_handler(lv_obj_t * obj, lv_event_t event) void toggle_event_handler(lv_obj_t * obj, lv_event_t event)
{ {
if(event == LV_EVENT_VALUE_CHANGED) { if(event == LV_EVENT_VALUE_CHANGED) {
char property[4];
bool val = 0;
hasp_update_sleep_state(); // wakeup? hasp_update_sleep_state(); // wakeup?
hasp_send_obj_attribute_val(obj, lv_switch_get_state(obj));
switch(obj->user_data.objid) {
case LV_HASP_SWITCH:
val = lv_switch_get_state(obj);
break;
case LV_HASP_CHECKBOX:
val = lv_checkbox_is_checked(obj);
break;
case LV_HASP_BUTTON: {
val = lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_CHECKED;
break;
}
default:
return;
}
snprintf_P(property, sizeof(property), PSTR("val"));
hasp_send_obj_attribute_int(obj, property, val);
dispatch_normalized_group_value(obj->user_data.groupid, NORMALIZE(val, 0, 1), obj);
} else if(event == LV_EVENT_DELETE) { } else if(event == LV_EVENT_DELETE) {
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event); Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
hasp_object_delete(obj); hasp_object_delete(obj);
@ -381,22 +390,7 @@ static void switch_event_handler(lv_obj_t * obj, lv_event_t event)
} }
/** /**
* Called when a checkboxed is clicked * Called when a range value has changed
* @param obj pointer to a checkbox
* @param event type of event that occured
*/
static void checkbox_event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
hasp_send_obj_attribute_val(obj, lv_checkbox_is_checked(obj));
} else if(event == LV_EVENT_DELETE) {
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
hasp_object_delete(obj);
}
}
/**
* Called when a dropdown or roller list is clicked
* @param obj pointer to a dropdown list or roller * @param obj pointer to a dropdown list or roller
* @param event type of event that occured * @param event type of event that occured
*/ */
@ -406,17 +400,19 @@ static void selector_event_handler(lv_obj_t * obj, lv_event_t event)
char buffer[128]; char buffer[128];
char property[36]; char property[36];
uint16_t val = 0; uint16_t val = 0;
uint16_t max = 0;
hasp_update_sleep_state(); // wakeup? hasp_update_sleep_state(); // wakeup?
switch(obj->user_data.objid) { switch(obj->user_data.objid) {
case LV_HASP_DDLIST: case LV_HASP_DDLIST:
val = lv_dropdown_get_selected(obj); val = lv_dropdown_get_selected(obj);
max = lv_dropdown_get_option_cnt(obj) - 1;
lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer));
break; break;
case LV_HASP_ROLLER: case LV_HASP_ROLLER:
val = lv_roller_get_selected(obj); val = lv_roller_get_selected(obj);
max = lv_roller_get_option_cnt(obj) - 1;
lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); lv_roller_get_selected_str(obj, buffer, sizeof(buffer));
break; break;
@ -436,17 +432,19 @@ static void selector_event_handler(lv_obj_t * obj, lv_event_t event)
strncpy(buffer, txt, sizeof(buffer)); strncpy(buffer, txt, sizeof(buffer));
snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"txt"), row, col); snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"txt"), row, col);
goto property_set; hasp_send_obj_attribute_str(obj, property, buffer);
return;
} }
default: default:
return; return;
} }
// set the property // set the property
snprintf_P(property, sizeof(property), PSTR("val\":%d,\"txt"), val); snprintf_P(property, sizeof(property), PSTR("val\":%d,\"txt"), val);
property_set:
hasp_send_obj_attribute_str(obj, property, buffer); hasp_send_obj_attribute_str(obj, property, buffer);
if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, NORMALIZE(val, 0, max), obj);
} else if(event == LV_EVENT_DELETE) { } else if(event == LV_EVENT_DELETE) {
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event); Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
hasp_object_delete(obj); hasp_object_delete(obj);
@ -474,15 +472,23 @@ void slider_event_handler(lv_obj_t * obj, lv_event_t event)
} }
*/ */
int16_t val; int16_t val = 0;
int16_t min = 0;
int16_t max = 0;
if(obj->user_data.objid == LV_HASP_SLIDER) { if(obj->user_data.objid == LV_HASP_SLIDER) {
val = lv_slider_get_value(obj); val = lv_slider_get_value(obj);
min = lv_slider_get_min_value(obj);
max = lv_slider_get_max_value(obj);
} else if(obj->user_data.objid == LV_HASP_ARC) { } else if(obj->user_data.objid == LV_HASP_ARC) {
val = lv_arc_get_value(obj); val = lv_arc_get_value(obj);
min = lv_arc_get_min_value(obj);
max = lv_arc_get_max_value(obj);
} else { } else {
return; return;
} }
hasp_send_obj_attribute_val(obj, lv_slider_get_value(obj)); dispatch_object_value_changed(obj, val);
dispatch_normalized_group_value(obj->user_data.groupid, NORMALIZE(val, min, max), obj);
} else if(event == LV_EVENT_DELETE) { } else if(event == LV_EVENT_DELETE) {
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event); Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
@ -501,6 +507,7 @@ static void cpicker_event_handler(lv_obj_t * obj, lv_event_t event)
snprintf_P(color, sizeof(color), PSTR("color")); snprintf_P(color, sizeof(color), PSTR("color"));
if(event == LV_EVENT_VALUE_CHANGED) { if(event == LV_EVENT_VALUE_CHANGED) {
hasp_update_sleep_state(); // wakeup?
hasp_send_obj_attribute_color(obj, color, lv_cpicker_get_color(obj)); hasp_send_obj_attribute_color(obj, color, lv_cpicker_get_color(obj));
} else if(event == LV_EVENT_DELETE) { } else if(event == LV_EVENT_DELETE) {
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event); Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
@ -513,18 +520,60 @@ static void cpicker_event_handler(lv_obj_t * obj, lv_event_t event)
// TODO make this a recursive function that goes over all objects only ONCE // TODO make this a recursive function that goes over all objects only ONCE
void object_set_group_state(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj) void object_set_group_state(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj)
{ {
if(groupid == 0) return;
bool state = dispatch_get_event_state(eventid); bool state = dispatch_get_event_state(eventid);
for(uint8_t page = 0; page < HASP_NUM_PAGES; page++) { for(uint8_t page = 0; page < HASP_NUM_PAGES; page++) {
uint8_t startid = 100 + groupid * 10; // groups start at id 100 uint8_t startid = 1;
for(uint8_t objid = startid; objid < (startid + 10); objid++) { for(uint8_t objid = startid; objid < 20; objid++) {
lv_obj_t * obj = hasp_find_obj_from_parent_id(get_page_obj(page), objid); lv_obj_t * obj = hasp_find_obj_from_parent_id(get_page_obj(page), objid);
if(obj && obj != src_obj) { // skip source object, if set if(obj && obj != src_obj && obj->user_data.groupid == groupid) { // skip source object, if set
lv_obj_set_state(obj, state ? LV_STATE_PRESSED | LV_STATE_CHECKED : LV_STATE_DEFAULT); lv_obj_set_state(obj, state ? LV_STATE_PRESSED | LV_STATE_CHECKED : LV_STATE_DEFAULT);
} }
} }
} }
} }
void object_set_group_value(lv_obj_t * parent, uint8_t groupid, const char * payload)
{
if(groupid == 0 || parent == nullptr) return;
lv_obj_t * child;
child = lv_obj_get_child(parent, NULL);
while(child) {
/* child found, update it */
if(groupid == child->user_data.groupid) hasp_process_obj_attribute_val(child, NULL, payload, true);
/* update grandchildren */
object_set_group_value(child, groupid, payload);
/* check tabs */
if(check_obj_type(child, LV_HASP_TABVIEW)) {
//#if LVGL_VERSION_MAJOR == 7
uint16_t tabcount = lv_tabview_get_tab_count(child);
for(uint16_t i = 0; i < tabcount; i++) {
lv_obj_t * tab = lv_tabview_get_tab(child, i);
Log.verbose(TAG_HASP, F("Found tab %i"), i);
if(tab->user_data.groupid && groupid == tab->user_data.groupid)
hasp_process_obj_attribute_val(tab, NULL, payload, true); /* tab found, update it */
/* check grandchildren */
object_set_group_value(tab, groupid, payload);
}
//#endif
}
/* try next sibling */
child = lv_obj_get_child(parent, child);
}
}
void object_set_group_value(uint8_t groupid, int16_t state)
{
char payload[16];
itoa(state, payload, DEC);
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Used in the dispatcher & hasp_new_object // Used in the dispatcher & hasp_new_object
@ -633,7 +682,7 @@ void hasp_new_object(const JsonObject & config, uint8_t & saved_page_id)
case HASP_OBJ_CB: case HASP_OBJ_CB:
obj = lv_checkbox_create(parent_obj, NULL); obj = lv_checkbox_create(parent_obj, NULL);
if(obj) { if(obj) {
lv_obj_set_event_cb(obj, checkbox_event_handler); lv_obj_set_event_cb(obj, toggle_event_handler);
obj->user_data.objid = LV_HASP_CHECKBOX; obj->user_data.objid = LV_HASP_CHECKBOX;
} }
break; break;
@ -859,7 +908,7 @@ void hasp_new_object(const JsonObject & config, uint8_t & saved_page_id)
case HASP_OBJ_SWITCH: case HASP_OBJ_SWITCH:
obj = lv_switch_create(parent_obj, NULL); obj = lv_switch_create(parent_obj, NULL);
if(obj) { if(obj) {
lv_obj_set_event_cb(obj, switch_event_handler); lv_obj_set_event_cb(obj, toggle_event_handler);
obj->user_data.objid = LV_HASP_SWITCH; obj->user_data.objid = LV_HASP_SWITCH;
} }
break; break;

View File

@ -70,8 +70,8 @@ void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, co
void object_set_group_state(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj); void object_set_group_state(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj);
void IRAM_ATTR generic_event_handler(lv_obj_t * obj, lv_event_t event); void generic_event_handler(lv_obj_t * obj, lv_event_t event);
void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event); void toggle_event_handler(lv_obj_t * obj, lv_event_t event);
void slider_event_handler(lv_obj_t * obj, lv_event_t event); void slider_event_handler(lv_obj_t * obj, lv_event_t event);
void wakeup_event_handler(lv_obj_t * obj, lv_event_t event); void wakeup_event_handler(lv_obj_t * obj, lv_event_t event);

View File

@ -49,30 +49,44 @@ static void gpio_event_handler(AceButton * button, uint8_t eventType, uint8_t bu
{ {
uint8_t btnid = button->getId(); uint8_t btnid = button->getId();
uint8_t eventid; uint8_t eventid;
bool state = false;
switch(eventType) { switch(eventType) {
case AceButton::kEventPressed: case AceButton::kEventPressed:
if(gpioConfig[btnid].type == HASP_GPIO_SWITCH || gpioConfig[btnid].type == HASP_GPIO_SWITCH_INVERTED) {
eventid = HASP_EVENT_ON;
} else {
eventid = HASP_EVENT_DOWN; eventid = HASP_EVENT_DOWN;
}
state = true;
break; break;
case 2: // AceButton::kEventClicked: case 2: // AceButton::kEventClicked:
eventid = HASP_EVENT_SHORT; eventid = HASP_EVENT_SHORT;
break; break;
case AceButton::kEventDoubleClicked: // case AceButton::kEventDoubleClicked:
eventid = HASP_EVENT_DOUBLE; // eventid = HASP_EVENT_DOUBLE;
break; // break;
case AceButton::kEventLongPressed: case AceButton::kEventLongPressed:
eventid = HASP_EVENT_LONG; eventid = HASP_EVENT_LONG;
// state = true; // do not repeat DOWN + LONG
break; break;
case AceButton::kEventRepeatPressed: // case AceButton::kEventRepeatPressed:
// return; // Fix needed for switches // eventid = HASP_EVENT_HOLD;
eventid = HASP_EVENT_HOLD; // state = true; // do not repeat DOWN + LONG + HOLD
break; // break;
case AceButton::kEventReleased: case AceButton::kEventReleased:
if(gpioConfig[btnid].type == HASP_GPIO_SWITCH || gpioConfig[btnid].type == HASP_GPIO_SWITCH_INVERTED) {
eventid = HASP_EVENT_OFF;
} else {
eventid = HASP_EVENT_UP; eventid = HASP_EVENT_UP;
}
break; break;
default: default:
eventid = HASP_EVENT_LOST; eventid = HASP_EVENT_LOST;
} }
dispatch_gpio_event(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid);
dispatch_gpio_input_event(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid);
if(eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG
dispatch_normalized_group_value(gpioConfig[btnid].group, NORMALIZE(state, 0, 1), NULL);
} }
void aceButtonSetup(void) void aceButtonSetup(void)
@ -81,8 +95,8 @@ void aceButtonSetup(void)
buttonConfig->setEventHandler(gpio_event_handler); buttonConfig->setEventHandler(gpio_event_handler);
// Features // Features
buttonConfig->setFeature(ButtonConfig::kFeatureClick); // buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); // buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
// buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress); // buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
// buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick); // buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
// buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
@ -98,7 +112,7 @@ void aceButtonSetup(void)
void IRAM_ATTR gpioLoop(void) void IRAM_ATTR gpioLoop(void)
{ {
// Should be called every 4-5ms or faster, for the default debouncing time of ~20ms. // Should be called every 4-5ms or faster, for the default debouncing time of ~20ms.
for(uint32_t i = 0; i < gpioUsedInputCount; i++) { for(uint8_t i = 0; i < gpioUsedInputCount; i++) {
if(button[i]) button[i]->check(); if(button[i]) button[i]->check();
} }
} }
@ -113,19 +127,19 @@ void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8
input_mode, default_state); input_mode, default_state);
button[i] = new AceButton(pin, default_state, index); button[i] = new AceButton(pin, default_state, index);
// button[i]->init(pin, default_state, index);
if(button[i]) { if(button[i]) {
//pinMode(pin, input_mode); // pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig(); ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_handler); buttonConfig->setEventHandler(gpio_event_handler);
buttonConfig->setFeature(ButtonConfig::kFeatureClick); buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick); buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
//buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); // buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig->clearFeature( buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick);
Log.trace(TAG_GPIO, F("Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index, Log.trace(TAG_GPIO, F("Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index,
input_mode, default_state); input_mode, default_state);
@ -138,6 +152,35 @@ void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8
index, HASP_NUM_INPUTS); index, HASP_NUM_INPUTS);
} }
void gpioAddSwitch(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index)
{
uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) {
Log.notice(TAG_GPIO, F("Creating Switch%d on pin %d (index %d) mode %d default %d"), i, pin, index,
input_mode, default_state);
button[i] = new AceButton(pin, default_state, index);
if(button[i]) {
// pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_handler);
buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAll);
Log.trace(TAG_GPIO, F("Button%d switch on pin %d (index %d) mode %d default %d"), i, pin, index,
input_mode, default_state);
gpioUsedInputCount = i + 1;
return;
}
}
}
Log.error(TAG_GPIO, F("Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin,
index, HASP_NUM_INPUTS);
}
void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index) void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index)
{ {
uint8_t i; uint8_t i;
@ -173,7 +216,7 @@ void gpioSetup()
{ {
aceButtonSetup(); aceButtonSetup();
for(uint32_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
uint8_t input_mode; uint8_t input_mode;
switch(gpioConfig[i].gpio_function) { switch(gpioConfig[i].gpio_function) {
case OUTPUT: case OUTPUT:
@ -193,29 +236,36 @@ void gpioSetup()
switch(gpioConfig[i].type) { switch(gpioConfig[i].type) {
case HASP_GPIO_SWITCH: case HASP_GPIO_SWITCH:
gpioAddSwitch(gpioConfig[i].pin, input_mode, HIGH, i);
pinMode(gpioConfig[i].pin, INPUT_PULLUP);
break;
case HASP_GPIO_BUTTON: case HASP_GPIO_BUTTON:
gpioAddButton(gpioConfig[i].pin, input_mode, HIGH, i); gpioAddButton(gpioConfig[i].pin, input_mode, HIGH, i);
pinMode(gpioConfig[i].pin, INPUT_PULLUP); pinMode(gpioConfig[i].pin, INPUT_PULLUP);
break; break;
case HASP_GPIO_SWITCH_INVERTED: case HASP_GPIO_SWITCH_INVERTED:
gpioAddSwitch(gpioConfig[i].pin, input_mode, LOW, i);
pinMode(gpioConfig[i].pin, INPUT_PULLDOWN);
break;
case HASP_GPIO_BUTTON_INVERTED: case HASP_GPIO_BUTTON_INVERTED:
gpioAddButton(gpioConfig[i].pin, input_mode, LOW, i); gpioAddButton(gpioConfig[i].pin, input_mode, LOW, i);
pinMode(gpioConfig[i].pin, INPUT_PULLDOWN);
break; break;
case HASP_GPIO_RELAY: case HASP_GPIO_RELAY:
case HASP_GPIO_RELAY_INVERTED: case HASP_GPIO_RELAY_INVERTED:
case HASP_GPIO_LED:
case HASP_GPIO_LED_INVERTED:
pinMode(gpioConfig[i].pin, OUTPUT); pinMode(gpioConfig[i].pin, OUTPUT);
break; break;
case HASP_GPIO_LED:
case HASP_GPIO_LED_INVERTED:
case HASP_GPIO_PWM: case HASP_GPIO_PWM:
case HASP_GPIO_PWM_INVERTED: case HASP_GPIO_PWM_INVERTED:
// case HASP_GPIO_BACKLIGHT: // case HASP_GPIO_BACKLIGHT:
pinMode(gpioConfig[i].pin, OUTPUT); pinMode(gpioConfig[i].pin, OUTPUT);
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
// configure LED PWM functionalitites // configure LED PWM functionalitites
ledcSetup(gpioConfig[i].group, 20000, 10); ledcSetup(gpioConfig[i].group, 20000, 12);
// attach the channel to the GPIO to be controlled // attach the channel to the GPIO to be controlled
ledcAttachPin(gpioConfig[i].pin, gpioConfig[i].group); ledcAttachPin(gpioConfig[i].pin, gpioConfig[i].group);
#endif #endif
@ -224,57 +274,76 @@ void gpioSetup()
} }
} }
void gpio_set_state(hasp_gpio_config_t gpio, bool state) /* ********************************* State Setters *************************************** */
void gpio_set_normalized_value(hasp_gpio_config_t gpio, uint16_t state)
{ {
switch(gpio.type) { switch(gpio.type) {
case HASP_GPIO_RELAY: case HASP_GPIO_RELAY:
case HASP_GPIO_LED: gpio.val = state >= 0x8000U ? HIGH : LOW;
digitalWrite(gpio.pin, state ? HIGH : LOW); digitalWrite(gpio.pin, gpio.val);
break; break;
case HASP_GPIO_RELAY_INVERTED: case HASP_GPIO_RELAY_INVERTED:
case HASP_GPIO_LED_INVERTED: gpio.val = state >= 0x8000U ? LOW : HIGH;
digitalWrite(gpio.pin, state ? LOW : HIGH); digitalWrite(gpio.pin, gpio.val);
break; break;
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
case HASP_GPIO_LED:
case HASP_GPIO_PWM: case HASP_GPIO_PWM:
ledcWrite(gpio.group, map(state, 0, 1, 0, 1023)); // ledChannel and value gpio.val = map(state, 0, 0xFFFFU, 0, 4095);
ledcWrite(gpio.group, gpio.val); // ledChannel and value
break; break;
case HASP_GPIO_LED_INVERTED:
case HASP_GPIO_PWM_INVERTED: case HASP_GPIO_PWM_INVERTED:
ledcWrite(gpio.group, map(!state, 0, 1, 0, 1023)); // ledChannel and value gpio.val = map(0xFFFFU - state, 0, 0xFFFFU, 0, 4095);
ledcWrite(gpio.group, gpio.val); // ledChannel and value
break; break;
#else #else
case HASP_GPIO_LED:
case HASP_GPIO_PWM: case HASP_GPIO_PWM:
analogWrite(gpio.pin, map(state, 0, 1, 0, 1023)); analogWrite(gpio.pin, map(state, 0, 0xFFFFU, 0, 1023));
break; break;
case HASP_GPIO_LED_INVERTED:
case HASP_GPIO_PWM_INVERTED: case HASP_GPIO_PWM_INVERTED:
analogWrite(gpio.pin, map(!state, 0, 1, 0, 1023)); analogWrite(gpio.pin, map(0xFFFFU - state, 0, 0xFFFFU, 0, 1023));
break; break;
#endif #endif
default:; default:
}
}
void gpio_set_group_state(uint8_t groupid, uint8_t eventid)
{
bool state = dispatch_get_event_state(eventid);
for(uint32_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
if(gpioConfig[i].group == groupid) {
gpio_set_state(gpioConfig[i], state);
}
}
}
void gpio_set_gpio_state(uint8_t pin, uint8_t eventid)
{
bool state = dispatch_get_event_state(eventid);
for(uint32_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
if(gpioConfig[i].pin == pin) {
gpio_set_state(gpioConfig[i], state);
return; return;
} }
Log.verbose(TAG_GPIO, F(" * Group %d - Pin %d = %d"), gpio.group, gpio.pin, gpio.val);
}
// void gpio_set_group_onoff(uint8_t groupid, bool ison)
// {
// for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
// if(gpioConfig[i].group == groupid) {
// gpio_set_value(gpioConfig[i], ison ? gpioConfig[i].max : 0);
// }
// }
// }
void gpio_set_normalized_group_value(uint8_t groupid, uint16_t state)
{
// bool state = dispatch_get_event_state(eventid);
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
if(gpioConfig[i].group == groupid) {
gpio_set_normalized_value(gpioConfig[i], state);
}
} }
} }
// not used
// void gpio_set_gpio_value(uint8_t pin, uint16_t state)
// {
// // bool state = dispatch_get_event_state(eventid);
// for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
// if(gpioConfig[i].pin == pin) {
// gpio_set_value(gpioConfig[i], state);
// return;
// }
// }
// }
bool gpioIsSystemPin(uint8_t gpio) bool gpioIsSystemPin(uint8_t gpio)
{ {
if((gpio >= NUM_DIGITAL_PINS) // invalid pins if((gpio >= NUM_DIGITAL_PINS) // invalid pins
@ -376,9 +445,9 @@ bool gpioIsSystemPin(uint8_t gpio)
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
if((gpio >= 6) && (gpio <= 11)) return true; // VSPI if((gpio >= 6) && (gpio <= 11)) return true; // VSPI
#ifndef TFT_SPI_OVERLAP #ifndef TFT_SPI_OVERLAP
if((gpio >= 12) && (gpio <= 14)) return true; // HSPI if((gpio >= 12) && (gpio <= 14)) return true; // HSPI
#endif #endif
#endif #endif
return false; return false;
@ -386,8 +455,8 @@ bool gpioIsSystemPin(uint8_t gpio)
bool gpioInUse(uint8_t gpio) bool gpioInUse(uint8_t gpio)
{ {
for(uint32_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
if(gpioConfigInUse(i) && (gpioConfig[i].pin == gpio)) { if((gpioConfig[i].pin == gpio) && gpioConfigInUse(i)) {
return true; // pin matches and is in use return true; // pin matches and is in use
} }
} }
@ -397,7 +466,7 @@ bool gpioInUse(uint8_t gpio)
bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc) bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc)
{ {
// Input validation // TODO: Input validation
// ESP8266: Only Pullups except on gpio16 // ESP8266: Only Pullups except on gpio16
@ -463,7 +532,7 @@ bool gpioGetConfig(const JsonObject & settings)
/* Build new Gpio array if the count is not correct */ /* Build new Gpio array if the count is not correct */
if(i != HASP_NUM_GPIO_CONFIG) { if(i != HASP_NUM_GPIO_CONFIG) {
array = settings[FPSTR(F_GPIO_CONFIG)].to<JsonArray>(); // Clear JsonArray array = settings[FPSTR(F_GPIO_CONFIG)].to<JsonArray>(); // Clear JsonArray
for(uint32_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
uint32_t cur_val = gpioConfig[i].pin | (gpioConfig[i].group << 8) | (gpioConfig[i].type << 16) | uint32_t cur_val = gpioConfig[i].pin | (gpioConfig[i].group << 8) | (gpioConfig[i].type << 16) |
(gpioConfig[i].gpio_function << 24); (gpioConfig[i].gpio_function << 24);
array.add(cur_val); array.add(cur_val);

View File

@ -16,13 +16,15 @@ struct hasp_gpio_config_t
uint8_t group; // groupid uint8_t group; // groupid
uint8_t type; // switch, button, ... uint8_t type; // switch, button, ...
uint8_t gpio_function; // INPUT, OUTPUT, PULLUP, etc uint8_t gpio_function; // INPUT, OUTPUT, PULLUP, etc
uint16_t val;
}; };
void gpioSetup(void); void gpioSetup(void);
void IRAM_ATTR gpioLoop(void); void IRAM_ATTR gpioLoop(void);
void gpio_set_group_state(uint8_t groupid, uint8_t eventid); // void gpio_set_group_onoff(uint8_t groupid, bool ison);
void gpio_set_gpio_state(uint8_t pin, uint8_t eventid); void gpio_set_normalized_group_value(uint8_t groupid, uint16_t state);
// void gpio_set_gpio_state(uint8_t pin, uint16_t state);
bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc); bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc);
bool gpioIsSystemPin(uint8_t gpio); bool gpioIsSystemPin(uint8_t gpio);

View File

@ -1261,25 +1261,25 @@ void webHandleGpioConfig()
httpMessage += halGpioName(gpio); httpMessage += halGpioName(gpio);
httpMessage += F("</td><td>"); httpMessage += F("</td><td>");
switch(conf.type) { switch(conf.type & 0xfe) {
case HASP_GPIO_SWITCH: case HASP_GPIO_SWITCH:
case HASP_GPIO_SWITCH_INVERTED: // case HASP_GPIO_SWITCH_INVERTED:
httpMessage += F("Switch"); httpMessage += F("Switch");
break; break;
case HASP_GPIO_BUTTON: case HASP_GPIO_BUTTON:
case HASP_GPIO_BUTTON_INVERTED: // case HASP_GPIO_BUTTON_INVERTED:
httpMessage += F("Button"); httpMessage += F("Button");
break; break;
case HASP_GPIO_LED: case HASP_GPIO_LED:
case HASP_GPIO_LED_INVERTED: // case HASP_GPIO_LED_INVERTED:
httpMessage += F("Led"); httpMessage += F("Led");
break; break;
case HASP_GPIO_RELAY: case HASP_GPIO_RELAY:
case HASP_GPIO_RELAY_INVERTED: // case HASP_GPIO_RELAY_INVERTED:
httpMessage += F("Relay"); httpMessage += F("Relay");
break; break;
case HASP_GPIO_PWM: case HASP_GPIO_PWM:
case HASP_GPIO_PWM_INVERTED: // case HASP_GPIO_PWM_INVERTED:
httpMessage += F("PWM"); httpMessage += F("PWM");
break; break;
default: default:
@ -1290,14 +1290,12 @@ void webHandleGpioConfig()
httpMessage += conf.group; httpMessage += conf.group;
httpMessage += F("</td><td>"); httpMessage += F("</td><td>");
bool inverted = (conf.type == HASP_GPIO_BUTTON_INVERTED) || // bool inverted = (conf.type == HASP_GPIO_BUTTON_INVERTED) ||
(conf.type == HASP_GPIO_SWITCH_INVERTED) || (conf.type == HASP_GPIO_LED_INVERTED) || // (conf.type == HASP_GPIO_SWITCH_INVERTED) || (conf.type == HASP_GPIO_LED_INVERTED)
(conf.type == HASP_GPIO_RELAY_INVERTED) || (conf.type == HASP_GPIO_PWM_INVERTED); // || (conf.type == HASP_GPIO_RELAY_INVERTED) || (conf.type ==
if(inverted) { // HASP_GPIO_PWM_INVERTED);
httpMessage += F("High");
} else { httpMessage += (conf.type & 0x1) ? F("High") : F("Low");
httpMessage += F("Low");
}
httpMessage += F("</td><td><a href='/config/gpio/options?id="); httpMessage += F("</td><td><a href='/config/gpio/options?id=");
httpMessage += id; httpMessage += id;