Use hasp_update_value_t to dispatch normalized value updates

This commit is contained in:
fvanroie 2021-05-12 04:29:05 +02:00
parent 5961ce87de
commit 7b03c0ae83
7 changed files with 168 additions and 229 deletions

View File

@ -429,47 +429,20 @@ void dispatch_config(const char* topic, const char* payload)
#endif // HASP_USE_CONFIG
/********************************************** Output States ******************************************/
/*
static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const char* payload)
void dispatch_normalized_group_values(hasp_update_value_t& value)
{
if(value.group == 0) return;
}*/
// 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 = Parser::get_event_state(eventid);
// gpio_set_group_onoff(groupid, state);
// object_set_normalized_group_value(groupid, eventid, obj);
// }
// char payload[8];
// Parser::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_normalized_group_value(groupid, state, obj);
// }
// char payload[8];
// // dispatch_output_group_state(groupid, payload);
// }
void dispatch_normalized_group_values(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max)
{
if(groupid == 0) return;
LOG_VERBOSE(TAG_MSGR, F("GROUP %d value %d (%d-%d)"), groupid, val, min, max);
LOG_VERBOSE(TAG_MSGR, F("GROUP %d value %d (%d-%d)"), value.group, value.val, value.min, value.max);
#if HASP_USE_GPIO > 0
gpio_set_normalized_group_values(groupid, val, min, max); // Update GPIO states
gpio_set_normalized_group_values(value); // Update GPIO states first
#endif
object_set_normalized_group_values(value); // Update onsreen objects except originating obj
#if HASP_USE_GPIO > 0
gpio_output_group_values(value.group); // Output new gpio values
#endif
object_set_normalized_group_values(groupid, obj, val, min, max); // Update onsreen objects
}
/********************************************** Native Commands ****************************************/

View File

@ -71,7 +71,7 @@ void dispatch_wakeup(const char*, const char*);
void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid);
void dispatch_output_pin_value(uint8_t pin, uint16_t val);
void dispatch_normalized_group_values(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max);
void dispatch_normalized_group_values(hasp_update_value_t& value);
void dispatch_state_subtopic(const char* subtopic, const char* payload);

View File

@ -239,6 +239,18 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16
// ##################### Event Handlers ########################################################
static inline void event_update_group(uint8_t group, lv_obj_t* obj, int32_t val, int32_t min, int32_t max)
{
hasp_update_value_t value = {
.min = min,
.max = max,
.val = val,
.obj = obj,
.group = group,
};
dispatch_normalized_group_values(value);
}
#if HASP_USE_GPIO > 0
void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid)
{
@ -448,8 +460,8 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event)
// Update group objects and gpios on release
if(last_value_sent == HASP_EVENT_UP || last_value_sent == HASP_EVENT_RELEASE) {
dispatch_normalized_group_values(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent),
HASP_EVENT_OFF, HASP_EVENT_ON);
event_update_group(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent), HASP_EVENT_OFF,
HASP_EVENT_ON);
}
}
@ -491,8 +503,8 @@ void toggle_event_handler(lv_obj_t* obj, lv_event_t event)
event_object_val_event(obj, hasp_event_id, last_value_sent);
// Update group objects and gpios on release
if(last_value_sent == HASP_EVENT_UP) {
dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON);
if(obj->user_data.groupid && hasp_event_id == HASP_EVENT_UP) {
event_update_group(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON);
}
}
@ -558,9 +570,9 @@ void selector_event_handler(lv_obj_t* obj, lv_event_t event)
last_value_sent = val;
event_object_selection_changed(obj, hasp_event_id, val, buffer);
if(max > 0) // max a cannot be 0, its the divider
if(obj->user_data.groupid && max > 0) // max a cannot be 0, its the divider
if(hasp_event_id == HASP_EVENT_UP || hasp_event_id == LV_EVENT_VALUE_CHANGED) {
dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, 0, max);
event_update_group(obj->user_data.groupid, obj, last_value_sent, 0, max);
}
// set the property
@ -599,7 +611,7 @@ void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event)
// if(max > 0) // max a cannot be 0, its the divider
// if(hasp_event_id == HASP_EVENT_UP || hasp_event_id == LV_EVENT_VALUE_CHANGED) {
// dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, 0, max);
// event_update_group(obj->user_data.groupid, obj, last_value_sent, 0, max);
// }
}
@ -632,7 +644,7 @@ void msgbox_event_handler(lv_obj_t* obj, lv_event_t event)
last_value_sent = val;
event_object_selection_changed(obj, hasp_event_id, val, buffer);
// if(max > 0) dispatch_normalized_group_values(obj->user_data.groupid, obj, val, 0, max);
// if(max > 0) event_update_group(obj->user_data.groupid, obj, val, 0, max);
}
/**
@ -671,8 +683,8 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event)
last_value_sent = val;
event_object_val_event(obj, hasp_event_id, val);
if(hasp_event_id == HASP_EVENT_CHANGED && min != max)
dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max);
if(obj->user_data.groupid && hasp_event_id == HASP_EVENT_CHANGED && min != max)
event_update_group(obj->user_data.groupid, obj, val, min, max);
}
/**
@ -704,7 +716,7 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue);
event_send_object_data(obj, data);
// dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max);
// event_update_group(obj->user_data.groupid, obj, val, min, max);
}
void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
@ -736,5 +748,5 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
eventname, date->day, date->year, date->month, date->day);
event_send_object_data(obj, data);
// dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max);
// event_update_group(obj->user_data.groupid, obj, val, min, max);
}

View File

@ -165,48 +165,42 @@ void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload)
// ##################### State Changers ########################################################
void object_set_group_values(lv_obj_t* parent, uint8_t groupid, int16_t intval)
// Recursive function that goes over all objects only ONCE
void object_set_group_values(lv_obj_t* parent, hasp_update_value_t& value)
{
if(groupid == 0 || parent == nullptr) return;
if(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, intval, intval, true);
// Update object if it's in the same group
if(value.group == parent->user_data.groupid && value.obj != parent)
hasp_process_obj_attribute_val(parent, NULL, value.val, !!value.val, true);
/* update grandchildren */
object_set_group_values(child, groupid, intval);
/* check tabs */
if(obj_check_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, intval, intval, true); /* tab found, update it */
/* check grandchildren */
object_set_group_values(tab, groupid, intval);
}
//#endif
/* check tabs */
if(obj_get_type(parent) == LV_HASP_TABVIEW) {
uint16_t tabcount = lv_tabview_get_tab_count(parent);
for(uint16_t i = 0; i < tabcount; i++) {
lv_obj_t* tab = lv_tabview_get_tab(parent, i);
object_set_group_values(tab, value);
}
} else {
lv_obj_t* child;
child = lv_obj_get_child(parent, NULL);
while(child) {
object_set_group_values(child, value);
child = lv_obj_get_child(parent, child);
}
/* try next sibling */
child = lv_obj_get_child(parent, child);
}
}
// Recursive function that goes over all objects only ONCE
void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max)
// SHOULD only by called from DISPATCH
void object_set_normalized_group_values(hasp_update_value_t& value)
{
if(groupid == 0) return;
if(min == max) return;
if(value.group == 0 || value.min == value.max) return;
for(uint8_t page = 0; page < HASP_NUM_PAGES; page++) {
object_set_group_values(haspPages.get_obj(page), groupid, val);
uint8_t page = haspPages.get();
object_set_group_values(haspPages.get_obj(page), value); // Update visible objects first
for(uint8_t i = 0; i < HASP_NUM_PAGES; i++) {
if(i != page) object_set_group_values(haspPages.get_obj(i), value);
// uint8_t startid = 1;
// for(uint8_t objid = startid; objid < 20; objid++) {
// lv_obj_t* obj = hasp_find_obj_from_parent_id(get_page_obj(page), objid);

View File

@ -20,6 +20,15 @@ typedef struct
uint16_t interval;
} hasp_task_user_data_t;
typedef struct
{
int32_t min;
int32_t max;
int32_t val;
lv_obj_t* obj;
uint8_t group;
} hasp_update_value_t;
enum lv_hasp_obj_type_t {
/* Containers */
LV_HASP_SCREEN = 1,
@ -81,7 +90,7 @@ void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload);
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload, bool update);
void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max);
void object_set_normalized_group_values(hasp_update_value_t& value);
#define HASP_OBJ_BAR 1971
#define HASP_OBJ_BTN 3164

View File

@ -16,10 +16,8 @@
#include "AceButton.h"
using namespace ace_button;
static AceButton* button[HASP_NUM_INPUTS];
ButtonConfig buttonConfig; // Clicks, double-clicks and long presses
ButtonConfig switchConfig; // Clicks only
#else
#define HIGH 1
@ -33,38 +31,52 @@ ButtonConfig switchConfig; // Clicks only
#define SCALE_8BIT_TO_12BIT(x) x << 4 | x >> 4
#define SCALE_8BIT_TO_10BIT(x) x << 2 | x >> 6
uint8_t gpioUsedInputCount = 0;
// An array of button pins, led pins, and the led states. Cannot be const
// because ledState is mutable.
hasp_gpio_config_t gpioConfig[HASP_NUM_GPIO_CONFIG] = {
// {2, 8, INPUT, LOW}, {3, 9, OUTPUT, LOW}, {4, 10, INPUT, HIGH}, {5, 11, OUTPUT, LOW}, {6, 12, INPUT, LOW},
};
static inline void gpio_update_group(uint8_t group, lv_obj_t* obj, int32_t val, int32_t min, int32_t max)
{
hasp_update_value_t value = {
.min = min,
.max = max,
.val = val,
.obj = obj,
.group = group,
};
dispatch_normalized_group_values(value);
}
#if defined(ARDUINO_ARCH_ESP32)
#include "driver/uart.h"
#include <driver/dac.h>
class TouchConfig : public ButtonConfig {
public:
TouchConfig();
volatile bool touchdetected = false;
void gotTouch()
{
touchdetected = true;
}
// Overrides the readButton function on ESP32
class CapacitiveConfig : public ButtonConfig {
protected:
// Number of iterations to sample the capacitive switch. Higher number
// provides better smoothing but increases the time taken for a single read.
static const uint8_t kSamples = 10;
// static const uint8_t kSamples = 10;
// The threshold value which is considered to be a "touch" on the switch.
static const long kTouchThreshold = 70;
static const long kTouchThreshold = 32;
int readButton(uint8_t pin) override
{
// long total = mSensor.capacitiveSensor(kSamples);
return (touchRead(pin) > kTouchThreshold) ? LOW : HIGH;
return touchdetected ? HIGH : LOW; // HIGH = not touched
}
};
TouchConfig touchConfig();
CapacitiveConfig touchConfig; // Capacitive touch
#endif
void gpio_log_serial_dimmer(const char* command)
@ -88,7 +100,8 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but
} else {
eventid = HASP_EVENT_DOWN;
}
state = true;
state = true;
touchdetected = false;
break;
case 2: // AceButton::kEventClicked:
eventid = HASP_EVENT_UP;
@ -116,8 +129,10 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but
}
event_gpio_input(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid);
if(eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG
dispatch_normalized_group_values(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON);
// update objects and gpios in this group
if(gpioConfig[btnid].group && eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG
gpio_update_group(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON);
}
/* ********************************* GPIO Setup *************************************** */
@ -129,11 +144,11 @@ void aceButtonSetup(void)
buttonConfig.setFeature(ButtonConfig::kFeatureClick);
buttonConfig.clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig.setFeature(ButtonConfig::kFeatureLongPress);
// buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
// buttonConfig.clearFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig.clearFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
buttonConfig.setFeature(ButtonConfig::kFeatureSuppressAfterClick);
buttonConfig.setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
// Delays
buttonConfig.setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig.setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig.setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig.setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
@ -146,68 +161,25 @@ void aceButtonSetup(void)
switchConfig.clearFeature(ButtonConfig::kFeatureRepeatPress);
switchConfig.clearFeature(ButtonConfig::kFeatureDoubleClick);
switchConfig.setClickDelay(100); // decrease click delay from default 200 ms
#if defined(ARDUINO_ARCH_ESP32)
// Capacitive Touch Features
touchConfig.setEventHandler(gpio_event_handler);
touchConfig.setFeature(ButtonConfig::kFeatureClick);
touchConfig.clearFeature(ButtonConfig::kFeatureDoubleClick);
touchConfig.setFeature(ButtonConfig::kFeatureLongPress);
// touchConfig.clearFeature(ButtonConfig::kFeatureRepeatPress);
touchConfig.clearFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
touchConfig.setFeature(ButtonConfig::kFeatureSuppressAfterClick);
// Delays
touchConfig.setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
touchConfig.setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
touchConfig.setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
touchConfig.setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
touchConfig.setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME);
#endif
}
/* void gpioAddButton(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_TRACE(TAG_GPIO, F("Creating Button%d on pin %d (index %d) mode %d default %d"), i, pin, index,
input_mode, default_state);
button[i] = new AceButton(&buttonConfig, pin, default_state, index);
if(button[i]) {
// pinMode(pin, input_mode);
// ButtonConfig* buttonConfig = button[i]->getButtonConfig();
// buttonConfig->setEventHandler(gpio_event_handler);
// buttonConfig->setFeature(ButtonConfig::kFeatureClick);
// buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
// buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
// // buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
// buttonConfig->clearFeature(
// ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
// buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick);
LOG_INFO(TAG_GPIO, F("Button%d created 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 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_TRACE(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(&switchConfig, pin, default_state, index);
if(button[i]) {
// pinMode(pin, input_mode);
LOG_INFO(TAG_GPIO, F("Switch%d 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 Switch%d pin %d (index %d). All %d slots available are in use!"), i, pin,
index, HASP_NUM_INPUTS);
}*/
// Can be called ad-hoc to change a setup
static void gpio_setup_pin(uint8_t index)
{
@ -240,13 +212,23 @@ static void gpio_setup_pin(uint8_t index)
switch(gpio->type) {
case HASP_GPIO_SWITCH:
config = &switchConfig;
case HASP_GPIO_BUTTON:
if(gpio->btn) delete gpio->btn;
gpio->btn = new AceButton(config, gpio->pin, HIGH, index);
gpio->btn = new AceButton(&switchConfig, gpio->pin, HIGH, index);
pinMode(gpio->pin, INPUT_PULLUP);
gpio->max = 0;
break;
case HASP_GPIO_BUTTON:
if(gpio->btn) delete gpio->btn;
gpio->btn = new AceButton(&buttonConfig, gpio->pin, HIGH, index);
pinMode(gpio->pin, INPUT_PULLUP);
gpio->max = 0;
break;
case HASP_GPIO_TOUCH:
if(gpio->btn) delete gpio->btn;
gpio->btn = new AceButton(&touchConfig, gpio->pin, HIGH, index);
gpio->max = 0;
// touchAttachInterrupt(gpio->pin, gotTouch, 33);
break;
case HASP_GPIO_RELAY:
pinMode(gpio->pin, OUTPUT);
@ -300,37 +282,6 @@ static void gpio_setup_pin(uint8_t index)
LOG_VERBOSE(TAG_GPIO, F(D_BULLET "Configured pin %d"), gpio->pin);
}
void gpioAddTouchButton(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]) {
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::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
LOG_INFO(TAG_GPIO, F("Button%d created 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 gpioSetup()
{
LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTING));
@ -462,7 +413,7 @@ bool gpio_get_pin_config(uint8_t pin, hasp_gpio_config_t** gpio)
return false;
}
// Update the actual value of one pin
// Update the actual value of one pin, does NOT update group members
// The value must be normalized first
static bool gpio_set_output_value(hasp_gpio_config_t* gpio, uint16_t val)
{
@ -492,7 +443,7 @@ static bool gpio_set_output_value(hasp_gpio_config_t* gpio, uint16_t val)
// Update the normalized value of one pin
void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int32_t val, int32_t min, int32_t max)
{
if(min != 0 || max != gpio->max) {
if(min != 0 || max != gpio->max) { // do we need to recalculate?
if(min == max) {
LOG_ERROR(TAG_GPIO, F("Invalid value range"));
return;
@ -511,51 +462,48 @@ void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int32_t val, int32_t mi
break;
default:
return;
return; // invalid output type
}
}
gpio_set_output_value(gpio, val); // normalized
gpio_set_output_value(gpio, val); // recalculated
}
/* void gpio_set_normalized_group_values(uint8_t groupid, int16_t val, int16_t min, int16_t max)
static inline bool gpio_is_input(hasp_gpio_config_t* gpio)
{
if(min == max) {
LOG_ERROR(TAG_GPIO, F("Invalid value range"));
return;
}
return gpio->type == HASP_GPIO_BUTTON || gpio->type == HASP_GPIO_SWITCH || gpio->type == HASP_GPIO_TOUCH;
}
// 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);
}
}
} */
static inline bool gpio_is_output(hasp_gpio_config_t* gpio)
{
return (gpio->type != HASP_GPIO_FREE) && !gpio_is_input(gpio);
}
// Dispatch all group member values
void gpio_output_group_values(uint8_t group)
{
for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) {
hasp_gpio_config_t* gpio = &gpioConfig[k];
if(gpio->group == group && gpio->type != HASP_GPIO_BUTTON &&
gpio->type != HASP_GPIO_SWITCH && // group members that are outputs
gpioConfigInUse(k))
if(gpio->group == group && gpio_is_output(gpio)) // group members that are outputs
dispatch_output_pin_value(gpioConfig[k].pin, gpioConfig[k].val);
}
}
// SHOULD only by called from DISPATCH
// Update the normalized value of all group members
void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, int32_t max)
// Does not procude logging output
void gpio_set_normalized_group_values(hasp_update_value_t& value)
{
// Set all pins first, minimizes delays
for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) {
hasp_gpio_config_t* gpio = &gpioConfig[k];
if(gpio->group == group && gpioConfigInUse(k)) // group members that are outputs
gpio_set_normalized_value(gpio, val, min, max);
if(gpio->group == value.group && gpioConfigInUse(k)) // group members that are outputs
gpio_set_normalized_value(gpio, value.val, value.min, value.max);
}
gpio_output_group_values(group);
object_set_normalized_group_values(group, NULL, val, min, max); // Update onsreen objects
// Log the changed output values
// gpio_output_group_values(value.group);
// object_set_normalized_group_values(group, NULL, val, min, max); // Update onsreen objects
}
// Update the value of an output pin and its group members
@ -563,22 +511,23 @@ bool gpio_set_pin_value(uint8_t pin, int32_t val)
{
hasp_gpio_config_t* gpio = NULL;
if(!gpio_get_pin_config(pin, &gpio) || !gpio || gpio->type == HASP_GPIO_FREE) {
if(!gpio_get_pin_config(pin, &gpio) || !gpio) {
LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin);
return false;
} else if(gpio->type == HASP_GPIO_BUTTON || gpio->type == HASP_GPIO_SWITCH) {
LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is an input"), pin);
} else if(gpio_is_output(gpio)) {
LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d can not be set"), pin);
if(gpio->group) gpio_output_group_values(gpio->group);
return false;
}
if(gpio->group) {
gpio_set_normalized_group_values(gpio->group, val, 0, gpio->max); // Set all pins in the group
LOG_VERBOSE(TAG_GPIO, F("Group %d - Pin %d = %d"), gpio->group, gpio->pin, gpio->val);
// update objects and gpios in this group
gpio_update_group(gpio->group, NULL, gpio->val, 0, gpio->max);
} else {
gpio_set_output_value(gpio, val); // update this gpio value only
// update this gpio value only
gpio_set_output_value(gpio, val);
dispatch_output_pin_value(gpio->pin, gpio->val);
LOG_VERBOSE(TAG_GPIO, F("No Group - Pin %d = %d"), gpio->pin, gpio->val);
}
@ -625,6 +574,8 @@ void gpio_set_moodlight(moodlight_t& moodlight)
break;
}
}
// TODO: Update objects when the Mood Color Pin is in a group
}
bool gpioIsSystemPin(uint8_t gpio)

View File

@ -34,9 +34,9 @@ void gpioSetup(void);
IRAM_ATTR void gpioLoop(void);
void gpioEvery5Seconds(void);
// void gpio_set_group_onoff(uint8_t groupid, bool ison);
void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, int32_t max);
// void gpio_set_gpio_state(uint8_t pin, uint16_t state);
void gpio_set_normalized_group_values(hasp_update_value_t& value);
void gpio_output_group_values(uint8_t group);
bool gpio_get_value(uint8_t pin, uint16_t& val);
bool gpio_set_pin_value(uint8_t pin, int32_t val);
void gpio_set_moodlight(moodlight_t& moodlight);