Add hasp_event

This commit is contained in:
fvanroie 2021-04-13 01:43:51 +02:00
parent f9a78afbaf
commit 394580fa45
13 changed files with 714 additions and 659 deletions

View File

@ -96,24 +96,6 @@ void dispatch_state_object(uint8_t pageid, uint8_t btnid, const char* payload)
dispatch_state_subtopic(topic, payload);
}
/* Takes and lv_obj and finds the pageid and objid
Then sends the data out on the state/pxby topic
*/
void dispatch_obj_data(lv_obj_t* obj, const char* data)
{
uint8_t pageid;
uint8_t objid;
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
if(!data) return;
#if HASP_USE_MQTT > 0
dispatch_state_object(pageid, objid, data);
#endif
} else {
LOG_ERROR(TAG_MSGR, F(D_OBJECT_UNKNOWN));
}
}
// Format filesystem and erase EEPROM
bool dispatch_factory_reset()
{
@ -233,6 +215,59 @@ static inline bool dispatch_parse_button_attribute(const char* topic_p, const ch
// }
}
static void dispatch_gpio(const char* topic, const char* payload)
{
int16_t val;
uint8_t pin;
if(topic == strstr_P(topic, PSTR("relay"))) {
if(strlen(payload) == 0) {
// val = gpio_get_relay_value(pin);
} else {
topic += 5;
if(Utilities::is_only_digits(topic)) {
pin = atoi(topic);
val = Utilities::is_true(payload);
// gpio_set_relay_value(pin, val);
return;
}
// invalid pin
}
} else if(topic == strstr_P(topic, PSTR("led"))) {
if(strlen(payload) == 0) {
} else {
topic += 3;
if(Utilities::is_only_digits(topic)) {
pin = atoi(topic);
val = Utilities::is_true(payload);
// gpio_set_led_value(pin, val);
return;
}
// invalid pin
}
} else if(topic == strstr_P(topic, PSTR("pwm"))) {
if(strlen(payload) == 0) {
} else {
topic += 3;
if(Utilities::is_only_digits(topic)) {
pin = atoi(topic);
val = Utilities::is_true(payload);
// gpio_set_pwm_value(pin, val);
return;
}
// invalid pin
}
} else {
LOG_WARNING(TAG_MSGR, F("Invalid gpio type %s"), topic);
return;
}
LOG_WARNING(TAG_MSGR, F("Invalid pin number %s"), topic);
}
// objectattribute=value
void dispatch_command(const char* topic, const char* payload)
{
@ -249,14 +284,9 @@ void dispatch_command(const char* topic, const char* payload)
/* =============================== Not standard payload commands ===================================== */
if(strlen(topic) == 7 && topic == strstr_P(topic, PSTR("output"))) {
if(topic == strstr_P(topic, PSTR("gpio/"))) {
if(strlen(payload) == 0) {
// reply state
} else {
int16_t state = atoi(payload);
dispatch_normalized_group_value(atoi(topic + 6), NULL, state, 0, 1); // + 6 => trim 'output' from the topic
}
dispatch_gpio(topic + 5, payload);
// } else if(strcasecmp_P(topic, PSTR("screenshot")) == 0) {
// guiTakeScreenshot("/screenshot.bmp"); // Literal String
@ -385,49 +415,17 @@ void dispatch_output_idle_state(uint8_t state)
dispatch_state_subtopic(topic, payload);
}
void dispatch_output_group_state(uint8_t groupid, uint16_t state)
{
char payload[64];
char number[16]; // Return the current state
char topic[8];
itoa(state, number, DEC);
snprintf_P(payload, sizeof(payload), PSTR("{\"group\":%d,\"state\":\"%s\"}"), groupid, number);
// void dispatch_output_group_state(uint8_t groupid, uint16_t state)
// {
// char payload[64];
// char number[16]; // Return the current state
// char topic[8];
// itoa(state, number, DEC);
// snprintf_P(payload, sizeof(payload), PSTR("{\"group\":%d,\"state\":\"%s\"}"), groupid, number);
memcpy_P(topic, PSTR("output"), 7);
dispatch_state_subtopic(topic, payload);
}
void dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char* attribute, const char* data)
{
if(!attribute || !data) return;
char payload[32 + strlen(data) + strlen(attribute)];
snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"%s\"}"), attribute, data);
dispatch_state_object(pageid, btnid, payload);
}
void dispatch_send_obj_attribute_int(uint8_t pageid, uint8_t btnid, const char* attribute, int32_t val)
{
if(!attribute) return;
char payload[64 + strlen(attribute)];
snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":%d}"), attribute, val);
dispatch_state_object(pageid, btnid, payload);
}
void dispatch_send_obj_attribute_color(uint8_t pageid, uint8_t btnid, const char* attribute, uint8_t r, uint8_t g,
uint8_t b)
{
if(!attribute) return;
char payload[64 + strlen(attribute)];
snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), attribute, r, g,
b, r, g, b);
dispatch_state_object(pageid, btnid, payload);
}
// memcpy_P(topic, PSTR("output"), 7);
// dispatch_state_subtopic(topic, payload);
// }
#if HASP_USE_CONFIG > 0
// Get or Set a part of the config.json file
@ -533,126 +531,18 @@ static void dispatch_config(const char* topic, const char* payload)
#endif // HASP_USE_CONFIG
/********************************************** Input Events *******************************************/
// Map events to either ON or OFF (UP or DOWN)
bool dispatch_get_event_state(uint8_t eventid)
{
switch(eventid) {
case HASP_EVENT_ON:
case HASP_EVENT_DOWN:
case HASP_EVENT_LONG:
case HASP_EVENT_HOLD:
return true;
// case HASP_EVENT_OFF:
// case HASP_EVENT_UP:
// case HASP_EVENT_SHORT:
// case HASP_EVENT_DOUBLE:
// case HASP_EVENT_LOST:
default:
return false;
}
}
// Map events to their description string
void dispatch_get_event_name(uint8_t eventid, char* buffer, size_t size)
{
switch(eventid) {
case HASP_EVENT_ON:
memcpy_P(buffer, PSTR("on"), size);
break;
case HASP_EVENT_OFF:
memcpy_P(buffer, PSTR("off"), size);
break;
case HASP_EVENT_UP:
memcpy_P(buffer, PSTR("up"), size);
break;
case HASP_EVENT_DOWN:
memcpy_P(buffer, PSTR("down"), size);
break;
case HASP_EVENT_SHORT:
memcpy_P(buffer, PSTR("short"), size);
break;
case HASP_EVENT_LONG:
memcpy_P(buffer, PSTR("long"), size);
break;
case HASP_EVENT_HOLD:
memcpy_P(buffer, PSTR("hold"), size);
break;
case HASP_EVENT_LOST:
memcpy_P(buffer, PSTR("lost"), size);
break;
case HASP_EVENT_CHANGED:
memcpy_P(buffer, PSTR("changed"), size);
break;
default:
memcpy_P(buffer, PSTR("unknown"), size);
}
}
#if HASP_USE_GPIO > 0
void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid)
void dispatch_gpio_output_value(const char* gpiotype, uint8_t pin, int16_t val)
{
char payload[64];
char topic[8];
char event[8];
dispatch_get_event_name(eventid, event, sizeof(event));
snprintf_P(payload, sizeof(payload), PSTR("{\"pin\":%d,\"group\":%d,\"event\":\"%s\"}"), pin, group, event);
char payload[16];
char topic[16];
snprintf_P(topic, sizeof(topic), PSTR("%s%d"), gpiotype, pin);
snprintf_P(payload, sizeof(payload), PSTR("%d"), val);
#if HASP_USE_MQTT > 0
memcpy_P(topic, PSTR("input"), 6);
dispatch_state_subtopic(topic, payload);
#endif
// update outputstates
// dispatch_group_onoff(group, dispatch_get_event_state(eventid), NULL);
}
#endif
/* ============================== Event Senders ============================ */
// Send out the event that occured
void dispatch_object_generic_event(lv_obj_t* obj, uint8_t eventid)
{
char data[40];
char eventname[8];
dispatch_get_event_name(eventid, eventname, sizeof(eventname));
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
dispatch_obj_data(obj, data);
}
// Send out the on/off event, with the val
void dispatch_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val)
{
char data[40];
char eventname[8];
dispatch_get_event_name(eventid, eventname, sizeof(eventname));
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
dispatch_obj_data(obj, data);
}
// Send out the changed event, with the val and text
void dispatch_object_selection_changed(lv_obj_t* obj, int16_t val, const char* text)
{
char data[200];
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"changed\",\"val\":%d,\"text\":\"%s\"}"), val, text);
dispatch_obj_data(obj, data);
}
// Send out the changed event, with the color
void dispatch_object_color_changed(lv_obj_t* obj, lv_color_t color)
{
char data[80];
lv_color32_t c32;
c32.full = lv_color_to32(color);
snprintf_P(data, sizeof(data),
PSTR("{\"event\":\"changed\",\"color\":\"#%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);
dispatch_obj_data(obj, data);
}
/********************************************** Output States ******************************************/
/*
static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const char* payload)
@ -665,13 +555,13 @@ static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const
// 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);
// bool state = Parser::get_event_state(eventid);
// gpio_set_group_onoff(groupid, state);
// object_set_normalized_group_value(groupid, eventid, obj);
// }
// char payload[8];
// dispatch_get_event_name(eventid, payload, sizeof(payload));
// Parser::get_event_name(eventid, payload, sizeof(payload));
// // dispatch_output_group_state(groupid, payload);
// }

View File

@ -65,21 +65,14 @@ void dispatch_current_state();
void dispatch_output_current_page();
void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid);
bool dispatch_get_event_state(uint8_t eventid);
void dispatch_get_event_name(uint8_t eventid, char* buffer, size_t size);
void dispatch_gpio_output_value(const char* gpiotype, uint8_t pin, int16_t val);
void dispatch_object_value_changed(lv_obj_t* obj, int16_t state);
void dispatch_normalized_group_value(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max);
void dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char* attribute, const char* data);
void dispatch_send_obj_attribute_int(uint8_t pageid, uint8_t btnid, const char* attribute, int32_t val);
void dispatch_send_obj_attribute_color(uint8_t pageid, uint8_t btnid, const char* attribute, uint8_t r, uint8_t g,
uint8_t b);
void dispatch_object_generic_event(lv_obj_t* obj, uint8_t eventid);
void dispatch_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val);
void dispatch_object_selection_changed(lv_obj_t* obj, int16_t val, const char* text);
void dispatch_object_color_changed(lv_obj_t* obj, lv_color_t color);
void dispatch_state_object(uint8_t pageid, uint8_t btnid, const char* payload);
void dispatch_state_subtopic(const char* subtopic, const char* payload);
/* ===== Getter and Setter Functions ===== */

496
src/hasp/hasp_event.cpp Normal file
View File

@ -0,0 +1,496 @@
/* MIT License - Copyright (c) 2019-2021 Francis Van Roie
For full license information read the LICENSE file in the project folder */
/* ********************************************************************************************
*
* HASP Event Handlers
* - Value Senders : Convert values and events into topic/payload before forwarding
* - Event Handlers : Callbacks for object event processing
*
******************************************************************************************** */
#include "hasp_conf.h"
#include "hasplib.h"
// static unsigned long last_change_event = 0;
static bool last_press_was_short = false; // Avoid SHORT + UP double events
static lv_style_int_t last_value_sent;
/* ============================== Event Senders ============================ */
/* Takes and lv_obj and finds the pageid and objid
Then sends the data out on the state/pxby topic
*/
// ##################### Value Senders ########################################################
void event_obj_data(lv_obj_t* obj, const char* data)
{
uint8_t pageid;
uint8_t objid;
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
if(!data) return;
#if HASP_USE_MQTT > 0
dispatch_state_object(pageid, objid, data);
#endif
} else {
LOG_ERROR(TAG_MSGR, F(D_OBJECT_UNKNOWN));
}
}
void event_dispatch(lv_obj_t* obj, uint8_t eventid, const char* data)
{}
// Send out the event that occured
void event_object_generic_event(lv_obj_t* obj, uint8_t eventid)
{
char data[40];
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname);
event_obj_data(obj, data);
}
// Send out the on/off event, with the val
void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val)
{
char data[40];
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val);
event_obj_data(obj, data);
}
// Send out the changed event, with the val and text
void event_object_selection_changed(lv_obj_t* obj, int16_t val, const char* text)
{
char data[200];
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"changed\",\"val\":%d,\"text\":\"%s\"}"), val, text);
event_obj_data(obj, data);
}
// Send out the changed event, with the color
void event_object_color_changed(lv_obj_t* obj, lv_color_t color)
{
char data[80];
lv_color32_t c32;
c32.full = lv_color_to32(color);
snprintf_P(data, sizeof(data),
PSTR("{\"event\":\"changed\",\"color\":\"#%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);
event_obj_data(obj, data);
}
// ##################### Event Handlers ########################################################
#if HASP_USE_GPIO > 0
void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid)
{
char payload[64];
char topic[8];
char event[8];
Parser::get_event_name(eventid, event, sizeof(event));
snprintf_P(payload, sizeof(payload), PSTR("{\"pin\":%d,\"group\":%d,\"event\":\"%s\"}"), pin, group, event);
memcpy_P(topic, PSTR("input"), 6);
dispatch_state_subtopic(topic, payload);
// update outputstates
// dispatch_group_onoff(group, Parser::get_event_state(eventid), NULL);
}
#endif
void event_delete_object(lv_obj_t* obj)
{
switch(obj->user_data.objid) {
case LV_HASP_LINE:
line_clear_points(obj);
break;
case LV_HASP_BTNMATRIX:
my_btnmatrix_map_clear(obj);
_LV_WIN_PART_REAL_LAST;
_LV_WIN_PART_VIRTUAL_LAST;
break;
case LV_HASP_GAUGE:
break;
}
// TODO: delete value_str data for ALL parts
my_obj_set_value_str_txt(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL);
}
void log_event(const char* name, lv_event_t event)
{
return;
switch(event) {
case LV_EVENT_PRESSED:
LOG_TRACE(TAG_EVENT, "%s Pressed", name);
break;
case LV_EVENT_PRESS_LOST:
LOG_TRACE(TAG_EVENT, "%s Press lost", name);
break;
case LV_EVENT_SHORT_CLICKED:
LOG_TRACE(TAG_EVENT, "%s Short clicked", name);
break;
case LV_EVENT_CLICKED:
LOG_TRACE(TAG_EVENT, "%s Clicked", name);
break;
case LV_EVENT_LONG_PRESSED:
LOG_TRACE(TAG_EVENT, "%S Long press", name);
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
LOG_TRACE(TAG_EVENT, "%s Long press repeat", name);
break;
case LV_EVENT_RELEASED:
LOG_TRACE(TAG_EVENT, "%s Released", name);
break;
case LV_EVENT_VALUE_CHANGED:
LOG_TRACE(TAG_EVENT, "%s Changed", name);
break;
case LV_EVENT_PRESSING:
break;
default:
LOG_TRACE(TAG_EVENT, "%s Other %d", name, event);
}
}
/**
* Called when a press on the system layer is detected
* @param obj pointer to a button matrix
* @param event type of event that occured
*/
void wakeup_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("wakeup", event);
if(event == LV_EVENT_RELEASED && obj == lv_disp_get_layer_sys(NULL)) {
hasp_update_sleep_state(); // wakeup?
if(!haspDevice.get_backlight_power())
dispatch_backlight(NULL, "1"); // backlight on and also disable wakeup touch
else {
hasp_disable_wakeup_touch(); // only disable wakeup touch
}
}
}
void page_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("page", event);
if(event == LV_EVENT_GESTURE) {
lv_gesture_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
switch(dir) {
case LV_GESTURE_DIR_LEFT:
haspPages.next(LV_SCR_LOAD_ANIM_NONE);
break;
case LV_GESTURE_DIR_RIGHT:
haspPages.prev(LV_SCR_LOAD_ANIM_NONE);
break;
case LV_GESTURE_DIR_BOTTOM:
haspPages.back(LV_SCR_LOAD_ANIM_NONE);
break;
}
}
}
/**
* Called when a button-style object is clicked
* @param obj pointer to a button object
* @param event type of event that occured
*/
void generic_event_handler(lv_obj_t* obj, lv_event_t event)
{
uint8_t eventid;
log_event("generic", event);
switch(event) {
case LV_EVENT_PRESSED:
eventid = HASP_EVENT_DOWN;
last_press_was_short = false;
break;
case LV_EVENT_CLICKED:
// UP = the same object was release then was pressed and press was not lost!
eventid = last_press_was_short ? HASP_EVENT_SHORT : HASP_EVENT_UP;
break;
case LV_EVENT_SHORT_CLICKED:
last_press_was_short = true; // Avoid SHORT + UP double events
return;
// eventid = HASP_EVENT_SHORT;
// break;
case LV_EVENT_LONG_PRESSED:
eventid = HASP_EVENT_LONG;
last_press_was_short = false;
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
// last_press_was_short = false;
return; // we don't care about hold
// eventid = HASP_EVENT_HOLD;
// break;
case LV_EVENT_PRESS_LOST:
eventid = HASP_EVENT_LOST;
last_press_was_short = false;
break;
case LV_EVENT_PRESSING:
case LV_EVENT_FOCUSED:
case LV_EVENT_DEFOCUSED:
case LV_EVENT_RELEASED:
return;
case LV_EVENT_VALUE_CHANGED:
LOG_WARNING(TAG_EVENT, F("Value changed Event %d occured"),
event); // Shouldn't happen in this event handler
last_press_was_short = false;
return;
case LV_EVENT_DELETE:
LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED));
event_delete_object(obj); // free and destroy persistent memory allocated for certain objects
last_press_was_short = false;
return;
default:
LOG_WARNING(TAG_EVENT, F(D_OBJECT_EVENT_UNKNOWN), event);
last_press_was_short = false;
return;
}
hasp_update_sleep_state(); // wakeup?
/* If an actionid is attached, perform that action on UP event only */
if(obj->user_data.actionid) {
if(eventid == HASP_EVENT_UP || eventid == HASP_EVENT_SHORT) {
lv_scr_load_anim_t transitionid = (lv_scr_load_anim_t)obj->user_data.transitionid;
switch(obj->user_data.actionid) {
case HASP_NUM_PAGE_PREV:
haspPages.prev(transitionid);
break;
case HASP_NUM_PAGE_BACK:
haspPages.back(transitionid);
break;
case HASP_NUM_PAGE_NEXT:
haspPages.next(transitionid);
break;
default:
haspPages.set(obj->user_data.actionid, transitionid);
}
dispatch_output_current_page();
}
} else {
event_object_generic_event(obj, eventid); // send normal object event
}
dispatch_normalized_group_value(obj->user_data.groupid, obj, Parser::get_event_state(eventid), HASP_EVENT_OFF,
HASP_EVENT_ON);
}
/**
* Called when a object state is toggled on/off
* @param obj pointer to a switch object
* @param event type of event that occured
*/
void toggle_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("toggle", event);
if(event == LV_EVENT_VALUE_CHANGED) {
bool val = 0;
hasp_update_sleep_state(); // wakeup?
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);
hasp_update_sleep_state(); // wakeup?
event_object_val_event(obj, val, val);
dispatch_normalized_group_value(obj->user_data.groupid, obj, val, HASP_EVENT_OFF, HASP_EVENT_ON);
} else if(event == LV_EVENT_DELETE) {
LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED));
event_delete_object(obj);
}
}
/**
* Called when a range value has changed
* @param obj pointer to a dropdown list or roller
* @param event type of event that occured
*/
void selector_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("selector", event);
if(event == LV_EVENT_VALUE_CHANGED) {
char buffer[128];
char property[36];
uint16_t val = 0;
uint16_t max = 0;
hasp_update_sleep_state(); // wakeup?
switch(obj->user_data.objid) {
case LV_HASP_DROPDOWN:
val = lv_dropdown_get_selected(obj);
max = lv_dropdown_get_option_cnt(obj) - 1;
lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer));
break;
case LV_HASP_ROLLER:
val = lv_roller_get_selected(obj);
max = lv_roller_get_option_cnt(obj) - 1;
lv_roller_get_selected_str(obj, buffer, sizeof(buffer));
break;
case LV_HASP_BTNMATRIX: {
val = lv_btnmatrix_get_active_btn(obj);
const char* txt = lv_btnmatrix_get_btn_text(obj, val);
strncpy(buffer, txt, sizeof(buffer));
break;
}
case LV_HASP_TABLE: {
uint16_t row;
uint16_t col;
if(lv_table_get_pressed_cell(obj, &row, &col) != LV_RES_OK) return; // outside any cell
const char* txt = lv_table_get_cell_value(obj, row, col);
strncpy(buffer, txt, sizeof(buffer));
snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"text"), row, col);
hasp_send_obj_attribute_str(obj, property, buffer);
return;
}
default:
return;
}
// set the property
// snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val);
// hasp_send_obj_attribute_str(obj, property, buffer);
event_object_selection_changed(obj, val, buffer);
if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max);
} else if(event == LV_EVENT_DELETE) {
LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED));
event_delete_object(obj);
}
}
/**
* Called when a slider or adjustable arc is clicked
* @param obj pointer to a slider
* @param event type of event that occured
*/
void slider_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("slider", event);
uint16_t evt;
switch(event) {
case LV_EVENT_VALUE_CHANGED:
break;
case LV_EVENT_DELETE:
LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED));
event_delete_object(obj);
break;
case LV_EVENT_PRESSED:
hasp_update_sleep_state(); // wakeup on press down?
evt = HASP_EVENT_DOWN;
case LV_EVENT_LONG_PRESSED_REPEAT:
if(event == LV_EVENT_LONG_PRESSED_REPEAT) evt = HASP_EVENT_CHANGED;
case LV_EVENT_RELEASED: {
if(event == LV_EVENT_RELEASED) evt = HASP_EVENT_UP;
// case LV_EVENT_PRESSED || LV_EVENT_LONG_PRESSED_REPEAT || LV_EVENT_RELEASED
int16_t val;
int16_t min;
int16_t max;
if(obj->user_data.objid == LV_HASP_SLIDER) {
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) {
val = lv_arc_get_value(obj);
min = lv_arc_get_min_value(obj);
max = lv_arc_get_max_value(obj);
} else {
return;
}
if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_value_sent != val) ||
event != LV_EVENT_LONG_PRESSED_REPEAT) {
last_value_sent = val;
event_object_val_event(obj, evt, val);
dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max);
}
break;
}
default:
// LOG_VERBOSE(TAG_EVENT, F("Event ID: %d"), event);
;
}
}
/**
* Called when a color picker is clicked
* @param obj pointer to a color picker
* @param event type of event that occured
*/
void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
{
char color[6];
snprintf_P(color, sizeof(color), PSTR("color"));
log_event("cpicker", event);
if(event == LV_EVENT_VALUE_CHANGED) {
hasp_update_sleep_state(); // wakeup?
// hasp_send_obj_attribute_color(obj, color, lv_cpicker_get_color(obj));
event_object_color_changed(obj, lv_cpicker_get_color(obj));
} else if(event == LV_EVENT_DELETE) {
LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED));
event_delete_object(obj);
}
}

26
src/hasp/hasp_event.h Normal file
View File

@ -0,0 +1,26 @@
/* MIT License - Copyright (c) 2019-2021 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_EVENT_H
#define HASP_EVENT_H
#include "lvgl.h"
#include "hasp_conf.h"
#define HASP_NUM_PAGE_PREV (HASP_NUM_PAGES + 1)
#define HASP_NUM_PAGE_BACK (HASP_NUM_PAGES + 2)
#define HASP_NUM_PAGE_NEXT (HASP_NUM_PAGES + 3)
void wakeup_event_handler(lv_obj_t* obj, lv_event_t event);
void page_event_handler(lv_obj_t* obj, lv_event_t event);
void generic_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 selector_event_handler(lv_obj_t* obj, lv_event_t event);
void cpicker_event_handler(lv_obj_t* obj, lv_event_t event);
#if HASP_USE_GPIO > 0
void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid);
#endif
#endif // HASP_EVENT_H

View File

@ -6,8 +6,6 @@
* HASP Object Handlers
* - Object Finders : Convert from object pointers to and from p[x].b[y] IDs
* - Value Dispatchers : Forward output data to the dispatcher
* - Value Senders : Convert values and events into topic/payload before forwarding
* - Event Handlers : Callbacks for object event processing
* - Attribute processor : Decide if an attribute needs updating or querying and forward
* - Object creator : Creates an object from a line of jsonl
*
@ -24,14 +22,7 @@
#include "hasplib.h"
#define HASP_NUM_PAGE_PREV (HASP_NUM_PAGES + 1)
#define HASP_NUM_PAGE_BACK (HASP_NUM_PAGES + 2)
#define HASP_NUM_PAGE_NEXT (HASP_NUM_PAGES + 3)
const char** btnmatrix_default_map; // memory pointer to lvgl default btnmatrix map
// static unsigned long last_change_event = 0;
static bool last_press_was_short = false; // Avoid SHORT + UP double events
static lv_style_int_t last_value_sent;
// ##################### Object Finders ########################################################
@ -231,7 +222,12 @@ void hasp_send_obj_attribute_str(lv_obj_t* obj, const char* attribute, const cha
uint8_t objid;
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
dispatch_send_obj_attribute_str(pageid, objid, attribute, data);
if(!attribute || !data) return;
char payload[32 + strlen(data) + strlen(attribute)];
snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"%s\"}"), attribute, data);
dispatch_state_object(pageid, objid, payload);
}
}
@ -241,7 +237,12 @@ void hasp_send_obj_attribute_int(lv_obj_t* obj, const char* attribute, int32_t v
uint8_t objid;
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
dispatch_send_obj_attribute_int(pageid, objid, attribute, val);
if(!attribute) return;
char payload[64 + strlen(attribute)];
snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":%d}"), attribute, val);
dispatch_state_object(pageid, objid, payload);
}
}
@ -251,408 +252,15 @@ void hasp_send_obj_attribute_color(lv_obj_t* obj, const char* attribute, lv_colo
uint8_t objid;
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
if(!attribute) return;
char payload[64 + strlen(attribute)];
lv_color32_t c32;
c32.full = lv_color_to32(color);
dispatch_send_obj_attribute_color(pageid, objid, attribute, c32.ch.red, c32.ch.green, c32.ch.blue);
}
}
// ##################### Value Senders ########################################################
// static void hasp_send_obj_attribute_P(lv_obj_t * obj, const char * attr, const char * data)
// {
// char * buffer;
// buffer = (char *)malloc(strlen_P(attr) + 1);
// strcpy_P(buffer, attr);
// hasp_send_obj_attribute_str(obj, buffer, data);
// free(buffer);
// }
// static inline void hasp_obj_value_changed(lv_obj_t * obj, int32_t val)
// {
// dispatch_object_value_changed(obj, val);
// char data[32];
// 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)
// {
// hasp_send_obj_attribute_P(obj, PSTR("event"), event);
// }
// static inline void hasp_send_obj_attribute_txt(lv_obj_t * obj, const char * txt)
// {
// hasp_send_obj_attribute_P(obj, PSTR("txt"), txt);
// }
// ##################### Event Handlers ########################################################
void log_event(const char* name, lv_event_t event)
{
return;
switch(event) {
case LV_EVENT_PRESSED:
LOG_TRACE(TAG_HASP, "%s Pressed", name);
break;
case LV_EVENT_PRESS_LOST:
LOG_TRACE(TAG_HASP, "%s Press lost", name);
break;
case LV_EVENT_SHORT_CLICKED:
LOG_TRACE(TAG_HASP, "%s Short clicked", name);
break;
case LV_EVENT_CLICKED:
LOG_TRACE(TAG_HASP, "%s Clicked", name);
break;
case LV_EVENT_LONG_PRESSED:
LOG_TRACE(TAG_HASP, "%S Long press", name);
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
LOG_TRACE(TAG_HASP, "%s Long press repeat", name);
break;
case LV_EVENT_RELEASED:
LOG_TRACE(TAG_HASP, "%s Released", name);
break;
case LV_EVENT_VALUE_CHANGED:
LOG_TRACE(TAG_HASP, "%s Changed", name);
break;
case LV_EVENT_PRESSING:
break;
default:
LOG_TRACE(TAG_HASP, "%s Other %d", name, event);
}
}
/**
* Called when a press on the system layer is detected
* @param obj pointer to a button matrix
* @param event type of event that occured
*/
void wakeup_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("wakeup", event);
if(event == LV_EVENT_RELEASED && obj == lv_disp_get_layer_sys(NULL)) {
hasp_update_sleep_state(); // wakeup?
if(!haspDevice.get_backlight_power())
dispatch_backlight(NULL, "1"); // backlight on and also disable wakeup touch
else {
hasp_disable_wakeup_touch(); // only disable wakeup touch
}
}
}
void page_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("page", event);
if(event == LV_EVENT_GESTURE) {
lv_gesture_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
switch(dir) {
case LV_GESTURE_DIR_LEFT:
haspPages.next(LV_SCR_LOAD_ANIM_NONE);
break;
case LV_GESTURE_DIR_RIGHT:
haspPages.prev(LV_SCR_LOAD_ANIM_NONE);
break;
case LV_GESTURE_DIR_BOTTOM:
haspPages.back(LV_SCR_LOAD_ANIM_NONE);
break;
}
}
}
/**
* Called when a button-style object is clicked
* @param obj pointer to a button object
* @param event type of event that occured
*/
void generic_event_handler(lv_obj_t* obj, lv_event_t event)
{
uint8_t eventid;
log_event("generic", event);
switch(event) {
case LV_EVENT_PRESSED:
eventid = HASP_EVENT_DOWN;
last_press_was_short = false;
break;
case LV_EVENT_CLICKED:
// UP = the same object was release then was pressed and press was not lost!
eventid = last_press_was_short ? HASP_EVENT_SHORT : HASP_EVENT_UP;
break;
case LV_EVENT_SHORT_CLICKED:
last_press_was_short = true; // Avoid SHORT + UP double events
return;
// eventid = HASP_EVENT_SHORT;
// break;
case LV_EVENT_LONG_PRESSED:
eventid = HASP_EVENT_LONG;
last_press_was_short = false;
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
// last_press_was_short = false;
return; // we don't care about hold
// eventid = HASP_EVENT_HOLD;
// break;
case LV_EVENT_PRESS_LOST:
eventid = HASP_EVENT_LOST;
last_press_was_short = false;
break;
case LV_EVENT_PRESSING:
case LV_EVENT_FOCUSED:
case LV_EVENT_DEFOCUSED:
case LV_EVENT_RELEASED:
return;
case LV_EVENT_VALUE_CHANGED:
LOG_WARNING(TAG_HASP, F("Value changed Event %d occured"), event); // Shouldn't happen in this event handler
last_press_was_short = false;
return;
case LV_EVENT_DELETE:
LOG_VERBOSE(TAG_HASP, F(D_OBJECT_DELETED));
hasp_object_delete(obj); // free and destroy persistent memory allocated for certain objects
last_press_was_short = false;
return;
default:
LOG_WARNING(TAG_HASP, F(D_OBJECT_EVENT_UNKNOWN), event);
last_press_was_short = false;
return;
}
hasp_update_sleep_state(); // wakeup?
/* If an actionid is attached, perform that action on UP event only */
if(obj->user_data.actionid) {
if(eventid == HASP_EVENT_UP || eventid == HASP_EVENT_SHORT) {
lv_scr_load_anim_t transitionid = (lv_scr_load_anim_t)obj->user_data.transitionid;
switch(obj->user_data.actionid) {
case HASP_NUM_PAGE_PREV:
haspPages.prev(transitionid);
break;
case HASP_NUM_PAGE_BACK:
haspPages.back(transitionid);
break;
case HASP_NUM_PAGE_NEXT:
haspPages.next(transitionid);
break;
default:
haspPages.set(obj->user_data.actionid, transitionid);
}
dispatch_output_current_page();
}
} else {
dispatch_object_generic_event(obj, eventid); // send normal object event
}
dispatch_normalized_group_value(obj->user_data.groupid, obj, dispatch_get_event_state(eventid), HASP_EVENT_OFF,
HASP_EVENT_ON);
}
/**
* Called when a object state is toggled on/off
* @param obj pointer to a switch object
* @param event type of event that occured
*/
void toggle_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("toggle", event);
if(event == LV_EVENT_VALUE_CHANGED) {
bool val = 0;
hasp_update_sleep_state(); // wakeup?
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);
hasp_update_sleep_state(); // wakeup?
dispatch_object_val_event(obj, val, val);
dispatch_normalized_group_value(obj->user_data.groupid, obj, val, HASP_EVENT_OFF, HASP_EVENT_ON);
} else if(event == LV_EVENT_DELETE) {
LOG_VERBOSE(TAG_HASP, F(D_OBJECT_DELETED));
hasp_object_delete(obj);
}
}
/**
* Called when a range value has changed
* @param obj pointer to a dropdown list or roller
* @param event type of event that occured
*/
static void selector_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("selector", event);
if(event == LV_EVENT_VALUE_CHANGED) {
char buffer[128];
char property[36];
uint16_t val = 0;
uint16_t max = 0;
hasp_update_sleep_state(); // wakeup?
switch(obj->user_data.objid) {
case LV_HASP_DROPDOWN:
val = lv_dropdown_get_selected(obj);
max = lv_dropdown_get_option_cnt(obj) - 1;
lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer));
break;
case LV_HASP_ROLLER:
val = lv_roller_get_selected(obj);
max = lv_roller_get_option_cnt(obj) - 1;
lv_roller_get_selected_str(obj, buffer, sizeof(buffer));
break;
case LV_HASP_BTNMATRIX: {
val = lv_btnmatrix_get_active_btn(obj);
const char* txt = lv_btnmatrix_get_btn_text(obj, val);
strncpy(buffer, txt, sizeof(buffer));
break;
}
case LV_HASP_TABLE: {
uint16_t row;
uint16_t col;
if(lv_table_get_pressed_cell(obj, &row, &col) != LV_RES_OK) return; // outside any cell
const char* txt = lv_table_get_cell_value(obj, row, col);
strncpy(buffer, txt, sizeof(buffer));
snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"text"), row, col);
hasp_send_obj_attribute_str(obj, property, buffer);
return;
}
default:
return;
}
// set the property
// snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val);
// hasp_send_obj_attribute_str(obj, property, buffer);
dispatch_object_selection_changed(obj, val, buffer);
if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max);
} else if(event == LV_EVENT_DELETE) {
LOG_VERBOSE(TAG_HASP, F(D_OBJECT_DELETED));
hasp_object_delete(obj);
}
}
/**
* Called when a slider or adjustable arc is clicked
* @param obj pointer to a slider
* @param event type of event that occured
*/
void slider_event_handler(lv_obj_t* obj, lv_event_t event)
{
log_event("slider", event);
uint16_t evt;
switch(event) {
case LV_EVENT_VALUE_CHANGED:
break;
case LV_EVENT_DELETE:
LOG_VERBOSE(TAG_HASP, F(D_OBJECT_DELETED));
hasp_object_delete(obj);
break;
case LV_EVENT_PRESSED:
hasp_update_sleep_state(); // wakeup on press down?
evt = HASP_EVENT_DOWN;
case LV_EVENT_LONG_PRESSED_REPEAT:
if(event == LV_EVENT_LONG_PRESSED_REPEAT) evt = HASP_EVENT_CHANGED;
case LV_EVENT_RELEASED: {
if(event == LV_EVENT_RELEASED) evt = HASP_EVENT_UP;
// case LV_EVENT_PRESSED || LV_EVENT_LONG_PRESSED_REPEAT || LV_EVENT_RELEASED
int16_t val;
int16_t min;
int16_t max;
if(obj->user_data.objid == LV_HASP_SLIDER) {
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) {
val = lv_arc_get_value(obj);
min = lv_arc_get_min_value(obj);
max = lv_arc_get_max_value(obj);
} else {
return;
}
if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_value_sent != val) ||
event != LV_EVENT_LONG_PRESSED_REPEAT) {
last_value_sent = val;
dispatch_object_val_event(obj, evt, val);
dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max);
}
break;
}
default:
// LOG_VERBOSE(TAG_HASP, F("Event ID: %d"), event);
;
}
}
/**
* Called when a color picker is clicked
* @param obj pointer to a color picker
* @param event type of event that occured
*/
static void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
{
char color[6];
snprintf_P(color, sizeof(color), PSTR("color"));
log_event("cpicker", event);
if(event == LV_EVENT_VALUE_CHANGED) {
hasp_update_sleep_state(); // wakeup?
// hasp_send_obj_attribute_color(obj, color, lv_cpicker_get_color(obj));
dispatch_object_color_changed(obj, lv_cpicker_get_color(obj));
} else if(event == LV_EVENT_DELETE) {
LOG_VERBOSE(TAG_HASP, F(D_OBJECT_DELETED));
hasp_object_delete(obj);
snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), attribute,
c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue);
dispatch_state_object(pageid, objid, payload);
}
}
@ -1181,24 +789,3 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id)
hasp_parse_json_attributes(obj, config);
}
void hasp_object_delete(lv_obj_t* obj)
{
switch(obj->user_data.objid) {
case LV_HASP_LINE:
line_clear_points(obj);
break;
case LV_HASP_BTNMATRIX:
my_btnmatrix_map_clear(obj);
_LV_WIN_PART_REAL_LAST;
_LV_WIN_PART_VIRTUAL_LAST;
break;
case LV_HASP_GAUGE:
break;
}
// TODO: delete value_str data for ALL parts
my_obj_set_value_str_txt(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL);
}

View File

@ -69,7 +69,6 @@ bool hasp_find_id_from_obj(lv_obj_t* obj, uint8_t* pageid, uint8_t* objid);
const char* get_obj_type_name(lv_obj_t* obj);
bool check_obj_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype);
void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level);
void hasp_object_delete(lv_obj_t* obj);
void hasp_send_obj_attribute_str(lv_obj_t* obj, const char* attribute, const char* data);
void hasp_send_obj_attribute_int(lv_obj_t* obj, const char* attribute, int32_t val);
@ -78,12 +77,6 @@ void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, con
void object_set_normalized_group_value(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max);
void wakeup_event_handler(lv_obj_t* obj, lv_event_t event);
void page_event_handler(lv_obj_t* obj, lv_event_t event);
void generic_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);
#define HASP_OBJ_BAR 1971
#define HASP_OBJ_BTN 3164
#define HASP_OBJ_CPICKER 3313

View File

@ -85,4 +85,59 @@ bool Parser::haspPayloadToColor(const char* payload, lv_color32_t& color)
#endif
return false; /* Color not found */
}
// Map events to either ON or OFF (UP or DOWN)
bool Parser::get_event_state(uint8_t eventid)
{
switch(eventid) {
case HASP_EVENT_ON:
case HASP_EVENT_DOWN:
case HASP_EVENT_LONG:
case HASP_EVENT_HOLD:
return true;
// case HASP_EVENT_OFF:
// case HASP_EVENT_UP:
// case HASP_EVENT_SHORT:
// case HASP_EVENT_DOUBLE:
// case HASP_EVENT_LOST:
default:
return false;
}
}
// Map events to their description string
void Parser::get_event_name(uint8_t eventid, char* buffer, size_t size)
{
switch(eventid) {
case HASP_EVENT_ON:
memcpy_P(buffer, PSTR("on"), size);
break;
case HASP_EVENT_OFF:
memcpy_P(buffer, PSTR("off"), size);
break;
case HASP_EVENT_UP:
memcpy_P(buffer, PSTR("up"), size);
break;
case HASP_EVENT_DOWN:
memcpy_P(buffer, PSTR("down"), size);
break;
case HASP_EVENT_SHORT:
memcpy_P(buffer, PSTR("short"), size);
break;
case HASP_EVENT_LONG:
memcpy_P(buffer, PSTR("long"), size);
break;
case HASP_EVENT_HOLD:
memcpy_P(buffer, PSTR("hold"), size);
break;
case HASP_EVENT_LOST:
memcpy_P(buffer, PSTR("lost"), size);
break;
case HASP_EVENT_CHANGED:
memcpy_P(buffer, PSTR("changed"), size);
break;
default:
memcpy_P(buffer, PSTR("unknown"), size);
}
}

View File

@ -11,6 +11,8 @@ class Parser {
public:
static bool haspPayloadToColor(const char* payload, lv_color32_t& color);
static bool get_event_state(uint8_t eventid);
static void get_event_name(uint8_t eventid, char* buffer, size_t size);
};
/* Named COLOR attributes */

View File

@ -223,6 +223,10 @@ void debug_get_tag(uint8_t tag, char* buffer)
memcpy_P(buffer, PSTR("MSGR"), 5);
break;
case TAG_EVENT:
memcpy_P(buffer, PSTR("EVNT"), 5);
break;
case TAG_OOBE:
memcpy_P(buffer, PSTR("OOBE"), 5);
break;

View File

@ -152,14 +152,15 @@ bool debugSetConfig(const JsonObject& settings);
#endif
enum {
TAG_MAIN = 0,
TAG_HASP = 1,
TAG_ATTR = 2,
TAG_MSGR = 3,
TAG_OOBE = 4,
TAG_HAL = 5,
TAG_DRVR = 6,
TAG_DEV = 7,
TAG_MAIN = 0,
TAG_HASP = 1,
TAG_ATTR = 2,
TAG_MSGR = 3,
TAG_OOBE = 4,
TAG_HAL = 5,
TAG_DRVR = 6,
TAG_DEV = 7,
TAG_EVENT = 8,
TAG_DEBG = 10,
TAG_TELN = 11,

View File

@ -3,6 +3,7 @@
#include "hasp/hasp.h"
#include "hasp/hasp_attribute.h"
#include "hasp/hasp_dispatch.h"
#include "hasp/hasp_event.h"
#include "hasp/hasp_object.h"
#include "hasp/hasp_page.h"
#include "hasp/hasp_parser.h"

View File

@ -8,6 +8,7 @@
#include "hasp/hasp.h"
#include "hasp/hasp_dispatch.h"
#include "hasp/hasp_parser.h"
#include "dev/device.h"
#include "hasp_mqtt.h"
@ -110,28 +111,28 @@ void mqtt_ha_register_button(uint8_t page, uint8_t id)
doc[F("atype")] = "trigger"; // automation_type
dispatch_get_event_name(HASP_EVENT_DOWN, buffer, sizeof(buffer));
Parser::get_event_name(HASP_EVENT_DOWN, buffer, sizeof(buffer));
doc[F("pl")] = buffer;
doc[F("type")] = "button_short_press";
snprintf_P(buffer, sizeof(buffer), PSTR("%s/device_automation/%s/" HASP_OBJECT_NOTATION "_%s/config"),
discovery_prefix, haspDevice.get_hostname(), page, id, "short_press");
mqtt_ha_send_json(buffer, doc);
dispatch_get_event_name(HASP_EVENT_SHORT, buffer, sizeof(buffer));
Parser::get_event_name(HASP_EVENT_SHORT, buffer, sizeof(buffer));
doc[F("pl")] = buffer;
doc[F("type")] = "button_short_release";
snprintf_P(buffer, sizeof(buffer), PSTR("%s/device_automation/%s/" HASP_OBJECT_NOTATION "_%s/config"),
discovery_prefix, haspDevice.get_hostname(), page, id, "short_release");
mqtt_ha_send_json(buffer, doc);
dispatch_get_event_name(HASP_EVENT_LONG, buffer, sizeof(buffer));
Parser::get_event_name(HASP_EVENT_LONG, buffer, sizeof(buffer));
doc[F("pl")] = buffer;
doc[F("type")] = "button_long_press";
snprintf_P(buffer, sizeof(buffer), PSTR("%s/device_automation/%s/" HASP_OBJECT_NOTATION "_%s/config"),
discovery_prefix, haspDevice.get_hostname(), page, id, "long_press");
mqtt_ha_send_json(buffer, doc);
dispatch_get_event_name(HASP_EVENT_UP, buffer, sizeof(buffer));
Parser::get_event_name(HASP_EVENT_UP, buffer, sizeof(buffer));
doc[F("pl")] = buffer;
doc[F("type")] = "button_long_release";
snprintf_P(buffer, sizeof(buffer), PSTR("%s/device_automation/%s/" HASP_OBJECT_NOTATION "_%s/config"),

View File

@ -4,13 +4,10 @@
#include "AceButton.h"
#include "lv_conf.h" // For timing defines
#include "hasp_conf.h"
#include "hasplib.h"
#include "hasp_gpio.h"
#include "hasp_config.h"
#include "hasp/hasp_dispatch.h"
#include "hasp/hasp.h"
#ifdef ARDUINO_ARCH_ESP8266
#define INPUT_PULLDOWN INPUT
#endif
@ -88,7 +85,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but
eventid = HASP_EVENT_LOST;
}
dispatch_gpio_input_event(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid);
event_gpio_input(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid);
if(eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG
dispatch_normalized_group_value(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON);
}
@ -290,11 +287,15 @@ void gpio_set_normalized_value(hasp_gpio_config_t gpio, int16_t val, int16_t min
case HASP_GPIO_RELAY:
gpio.val = val > min ? HIGH : LOW;
digitalWrite(gpio.pin, gpio.val);
dispatch_gpio_output_value("relay", gpio.pin, gpio.val);
break;
case HASP_GPIO_RELAY_INVERTED:
gpio.val = val > min ? LOW : HIGH;
digitalWrite(gpio.pin, gpio.val);
dispatch_gpio_output_value("relay", gpio.pin, gpio.val);
break;
case HASP_GPIO_LED:
case HASP_GPIO_LED_R:
case HASP_GPIO_LED_G:
@ -306,16 +307,9 @@ void gpio_set_normalized_value(hasp_gpio_config_t gpio, int16_t val, int16_t min
gpio.val = map(val, min, max, 0, 1023);
analogWrite(gpio.pin, gpio.val);
#endif
dispatch_gpio_output_value("led", gpio.pin, gpio.val);
break;
case HASP_GPIO_PWM:
#if defined(ARDUINO_ARCH_ESP32)
gpio.val = map(val, min, max, 0, 4095);
ledcWrite(gpio.group, gpio.val); // ledChannel and value
#else
gpio.val = map(val, min, max, 0, 1023);
analogWrite(gpio.pin, gpio.val);
#endif
break;
case HASP_GPIO_LED_INVERTED:
case HASP_GPIO_LED_R_INVERTED:
case HASP_GPIO_LED_G_INVERTED:
@ -328,6 +322,18 @@ void gpio_set_normalized_value(hasp_gpio_config_t gpio, int16_t val, int16_t min
gpio.val = map(val, min, max, 0, 1023);
analogWrite(gpio.pin, gpio.val);
#endif
dispatch_gpio_output_value("led", gpio.pin, gpio.val);
break;
case HASP_GPIO_PWM:
#if defined(ARDUINO_ARCH_ESP32)
gpio.val = map(val, min, max, 0, 4095);
ledcWrite(gpio.group, gpio.val); // ledChannel and value
#else
gpio.val = map(val, min, max, 0, 1023);
analogWrite(gpio.pin, gpio.val);
#endif
dispatch_gpio_output_value("pwm", gpio.pin, gpio.val);
break;
default:
@ -352,7 +358,7 @@ void gpio_set_normalized_group_value(uint8_t groupid, int16_t val, int16_t min,
return;
}
// bool state = dispatch_get_event_state(eventid);
// bool state = Parser::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], val, min, max);
@ -386,7 +392,7 @@ void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b)
// not used
// void gpio_set_gpio_value(uint8_t pin, uint16_t state)
// {
// // bool state = dispatch_get_event_state(eventid);
// // bool state = Parser::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);