|
|
|
@ -31,6 +31,7 @@
|
|
|
|
|
\*********************************************************************************************/
|
|
|
|
|
|
|
|
|
|
#define XDRV_35 35
|
|
|
|
|
#define MAX_PWM_DIMMER_KEYS 3
|
|
|
|
|
|
|
|
|
|
const char kPWMDimmerCommands[] PROGMEM = "|" // No prefix
|
|
|
|
|
D_CMND_BRI_PRESET
|
|
|
|
@ -58,26 +59,26 @@ struct remote_pwm_dimmer {
|
|
|
|
|
};
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
|
|
|
|
|
uint32_t ignore_any_key_time = 0;
|
|
|
|
|
uint32_t button_hold_time[3];
|
|
|
|
|
uint8_t led_timeout_seconds = 0;
|
|
|
|
|
uint8_t restore_powered_off_led_counter = 0;
|
|
|
|
|
uint8_t power_button_index = 0;
|
|
|
|
|
uint8_t down_button_index = 1;
|
|
|
|
|
uint8_t buttons_pressed = 0;
|
|
|
|
|
uint8_t local_fixed_color_index = 128;
|
|
|
|
|
bool ignore_power_button = false;
|
|
|
|
|
bool button_tapped = false;
|
|
|
|
|
bool down_button_tapped = false;
|
|
|
|
|
bool tap_handled = false;
|
|
|
|
|
bool ignore_power_button = false;
|
|
|
|
|
bool multibutton_in_progress = false;
|
|
|
|
|
bool power_button_increases_bri = true;
|
|
|
|
|
bool tap_handled = false;
|
|
|
|
|
bool invert_power_button_bri_direction = false;
|
|
|
|
|
bool button_pressed[3] = { false, false, false };
|
|
|
|
|
bool button_hold_sent[3];
|
|
|
|
|
bool button_hold_processed[3];
|
|
|
|
|
bool button_held[3];
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
struct remote_pwm_dimmer * remote_pwm_dimmers;
|
|
|
|
|
struct remote_pwm_dimmer remote_pwm_dimmers[MAX_PWM_DIMMER_KEYS];
|
|
|
|
|
struct remote_pwm_dimmer * active_remote_pwm_dimmer;
|
|
|
|
|
uint8_t remote_pwm_dimmer_count;
|
|
|
|
|
bool active_device_is_local;
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
|
|
|
|
|
void PWMModulePreInit(void)
|
|
|
|
@ -89,9 +90,14 @@ void PWMModulePreInit(void)
|
|
|
|
|
// If the module was just changed to PWM Dimmer, set the defaults.
|
|
|
|
|
if (Settings.last_module != Settings.module) {
|
|
|
|
|
Settings.flag.pwm_control = true; // SetOption15 - Switch between commands PWM or COLOR/DIMMER/CT/CHANNEL
|
|
|
|
|
Settings.param[P_HOLD_TIME] = 5; // SetOption32 - Button held for factor times longer
|
|
|
|
|
Settings.bri_power_on = Settings.bri_preset_low = Settings.bri_preset_high = 0;
|
|
|
|
|
Settings.last_module = Settings.module;
|
|
|
|
|
|
|
|
|
|
// Previous versions of PWM Dimmer used SetOption32 - Button held for factor times longer as the
|
|
|
|
|
// hold time. The hold time is now fixed and SetOption32 is used as normal including to
|
|
|
|
|
// determine how long a button is held before a reset command is executed. If SetOption32 is
|
|
|
|
|
// still 5, change it to 40 (the default).
|
|
|
|
|
if (Settings.param[P_HOLD_TIME] == 5) Settings.param[P_HOLD_TIME] = 40;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure the brightness level settings are sensible.
|
|
|
|
@ -111,54 +117,65 @@ void PWMModulePreInit(void)
|
|
|
|
|
Settings.flag4.device_groups_enabled = true;
|
|
|
|
|
|
|
|
|
|
device_group_count = 0;
|
|
|
|
|
for (uint32_t button_index = 0; button_index < MAX_KEYS; button_index++) {
|
|
|
|
|
for (uint32_t button_index = 0; button_index < MAX_PWM_DIMMER_KEYS; button_index++) {
|
|
|
|
|
if (PinUsed(GPIO_KEY1, button_index)) device_group_count++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
remote_pwm_dimmer_count = device_group_count - 1;
|
|
|
|
|
if (remote_pwm_dimmer_count) {
|
|
|
|
|
if ((remote_pwm_dimmers = (struct remote_pwm_dimmer *) calloc(remote_pwm_dimmer_count, sizeof(struct remote_pwm_dimmer))) == nullptr) {
|
|
|
|
|
AddLog_P2(LOG_LEVEL_ERROR, PSTR("PWMDimmer: error allocating PWM dimmer array"));
|
|
|
|
|
Settings.flag4.multiple_device_groups = false;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (uint8_t i = 0; i < remote_pwm_dimmer_count; i++) {
|
|
|
|
|
active_remote_pwm_dimmer = &remote_pwm_dimmers[i];
|
|
|
|
|
active_remote_pwm_dimmer->bri_power_on = 128;
|
|
|
|
|
active_remote_pwm_dimmer->bri_preset_low = 10;
|
|
|
|
|
active_remote_pwm_dimmer->bri_preset_high = 255;
|
|
|
|
|
active_remote_pwm_dimmer->fixed_color_index = 128;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// If no relay or PWM is defined, all buttons control remote devices.
|
|
|
|
|
if (!PinUsed(GPIO_REL1) && !PinUsed(GPIO_PWM1)) {
|
|
|
|
|
first_device_group_is_local = false;
|
|
|
|
|
|
|
|
|
|
// Back out the changes made in the light module under the assumtion we have a relay or PWM.
|
|
|
|
|
devices_present--;
|
|
|
|
|
light_type = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MAX_PWM_DIMMER_KEYS; i++) {
|
|
|
|
|
active_remote_pwm_dimmer = &remote_pwm_dimmers[i];
|
|
|
|
|
active_remote_pwm_dimmer->bri_power_on = 128;
|
|
|
|
|
active_remote_pwm_dimmer->bri_preset_low = 10;
|
|
|
|
|
active_remote_pwm_dimmer->bri_preset_high = 255;
|
|
|
|
|
active_remote_pwm_dimmer->fixed_color_index = 128;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
active_device_is_local = true;
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bri: -1 = set to current light bri, -2 = timeout, 0-255 = set to bri
|
|
|
|
|
void PWMDimmerSetBrightnessLeds(int32_t bri)
|
|
|
|
|
{
|
|
|
|
|
if (leds_present) {
|
|
|
|
|
// Find out how many of the LEDs have their ledmask bit set.
|
|
|
|
|
uint32_t leds = 0;
|
|
|
|
|
uint32_t mask = 1;
|
|
|
|
|
int32_t led;
|
|
|
|
|
for (led = 0; led < leds_present; led++) {
|
|
|
|
|
if (Settings.ledmask & mask) leds++;
|
|
|
|
|
mask <<= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we found at least one LED, get the brightness to show and calculate the brightness level
|
|
|
|
|
// difference between each LED.
|
|
|
|
|
if (leds) {
|
|
|
|
|
led_timeout_seconds = 5;
|
|
|
|
|
if (bri < 0) {
|
|
|
|
|
bri = ((bri == -2 && Settings.flag4.led_timeout) || !Light.power ? 0 : light_state.getBri());
|
|
|
|
|
if (!bri || !Settings.flag4.led_timeout) led_timeout_seconds = 0;
|
|
|
|
|
}
|
|
|
|
|
uint32_t step = 256 / (leds_present + 1);
|
|
|
|
|
uint32_t level = step;
|
|
|
|
|
SetLedPowerIdx(0, bri >= level);
|
|
|
|
|
if (leds_present > 1) {
|
|
|
|
|
uint32_t step = 256 / (leds + 1);
|
|
|
|
|
|
|
|
|
|
// Turn the LED's on/off.
|
|
|
|
|
uint32_t level = 0;
|
|
|
|
|
led = -1;
|
|
|
|
|
mask = 0;
|
|
|
|
|
for (uint32_t count = 0; count < leds; count++) {
|
|
|
|
|
level += step;
|
|
|
|
|
SetLedPowerIdx(1, bri >= level);
|
|
|
|
|
if (leds_present > 2) {
|
|
|
|
|
level += step;
|
|
|
|
|
SetLedPowerIdx(2, bri >= level);
|
|
|
|
|
if (leds_present > 3) {
|
|
|
|
|
level += step;
|
|
|
|
|
SetLedPowerIdx(3, bri >= level);
|
|
|
|
|
}
|
|
|
|
|
for (;;) {
|
|
|
|
|
led++;
|
|
|
|
|
mask <<= 1;
|
|
|
|
|
if (!mask) mask = 1;
|
|
|
|
|
if (Settings.ledmask & mask) break;
|
|
|
|
|
}
|
|
|
|
|
SetLedPowerIdx(led, bri >= level);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -183,105 +200,67 @@ void PWMDimmerSetPower(void)
|
|
|
|
|
#ifdef USE_DEVICE_GROUPS
|
|
|
|
|
void PWMDimmerHandleDevGroupItem(void)
|
|
|
|
|
{
|
|
|
|
|
uint32_t value = XdrvMailbox.payload;
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
uint8_t device_group_index = *(uint8_t *)XdrvMailbox.topic;
|
|
|
|
|
if (device_group_index > remote_pwm_dimmer_count) return;
|
|
|
|
|
bool device_is_local = device_groups[device_group_index].local;
|
|
|
|
|
struct remote_pwm_dimmer * remote_pwm_dimmer = &remote_pwm_dimmers[device_group_index - 1];
|
|
|
|
|
bool is_local = ((XdrvMailbox.index & DGR_FLAG_LOCAL) != 0);
|
|
|
|
|
if (device_group_index > MAX_PWM_DIMMER_KEYS) return;
|
|
|
|
|
struct remote_pwm_dimmer * remote_pwm_dimmer = &remote_pwm_dimmers[device_group_index];
|
|
|
|
|
#else // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (*(uint8_t *)XdrvMailbox.topic) return;
|
|
|
|
|
if (!(XdrvMailbox.index & DGR_FLAG_LOCAL)) return;
|
|
|
|
|
#endif // !USE_PWM_DIMMER_REMOTE
|
|
|
|
|
uint32_t value = XdrvMailbox.payload;
|
|
|
|
|
|
|
|
|
|
switch (XdrvMailbox.command_code) {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
case DGR_ITEM_LIGHT_BRI:
|
|
|
|
|
if (!device_is_local) remote_pwm_dimmer->bri = value;
|
|
|
|
|
remote_pwm_dimmer->bri = value;
|
|
|
|
|
break;
|
|
|
|
|
case DGR_ITEM_POWER:
|
|
|
|
|
if (!device_is_local) {
|
|
|
|
|
remote_pwm_dimmer->power_on = value & 1;
|
|
|
|
|
remote_pwm_dimmer->power_button_increases_bri = (remote_pwm_dimmer->bri < 128);
|
|
|
|
|
}
|
|
|
|
|
remote_pwm_dimmer->power_on = value & 1;
|
|
|
|
|
remote_pwm_dimmer->power_button_increases_bri = (remote_pwm_dimmer->bri < 128);
|
|
|
|
|
break;
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
case DGR_ITEM_LIGHT_FIXED_COLOR:
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!device_is_local)
|
|
|
|
|
remote_pwm_dimmer->fixed_color_index = value;
|
|
|
|
|
else
|
|
|
|
|
remote_pwm_dimmer->fixed_color_index = value;
|
|
|
|
|
if (is_local)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
local_fixed_color_index = value;
|
|
|
|
|
break;
|
|
|
|
|
case DGR_ITEM_BRI_POWER_ON:
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!device_is_local)
|
|
|
|
|
remote_pwm_dimmer->bri_power_on = value;
|
|
|
|
|
else
|
|
|
|
|
remote_pwm_dimmer->bri_power_on = value;
|
|
|
|
|
if (is_local)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
Settings.bri_power_on = value;
|
|
|
|
|
break;
|
|
|
|
|
case DGR_ITEM_BRI_PRESET_LOW:
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!device_is_local)
|
|
|
|
|
remote_pwm_dimmer->bri_preset_low = value;
|
|
|
|
|
else
|
|
|
|
|
remote_pwm_dimmer->bri_preset_low = value;
|
|
|
|
|
if (is_local)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
Settings.bri_preset_low = value;
|
|
|
|
|
break;
|
|
|
|
|
case DGR_ITEM_BRI_PRESET_HIGH:
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!device_is_local)
|
|
|
|
|
remote_pwm_dimmer->bri_preset_high = value;
|
|
|
|
|
else
|
|
|
|
|
remote_pwm_dimmer->bri_preset_high = value;
|
|
|
|
|
if (is_local)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
Settings.bri_preset_high = value;
|
|
|
|
|
break;
|
|
|
|
|
case DGR_ITEM_STATUS:
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (device_is_local)
|
|
|
|
|
if (is_local)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_BRI_POWER_ON, Settings.bri_power_on,
|
|
|
|
|
DGR_ITEM_BRI_PRESET_LOW, Settings.bri_preset_low, DGR_ITEM_BRI_PRESET_HIGH, Settings.bri_preset_high);
|
|
|
|
|
DGR_ITEM_BRI_PRESET_LOW, Settings.bri_preset_low, DGR_ITEM_BRI_PRESET_HIGH, Settings.bri_preset_high);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif // USE_DEVICE_GROUPS
|
|
|
|
|
|
|
|
|
|
void PWMDimmerHandleButton(void)
|
|
|
|
|
void PWMDimmerHandleButton(uint32_t button_index, bool pressed)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* Power Button Up/Down Buttons State Remote Mode Action
|
|
|
|
|
* -------------------- ---------------------- ----- ------------ ----------------------------
|
|
|
|
|
* Press & release Released Any Any Toggle power
|
|
|
|
|
* Hold for hold time Released On Any Brighter/dimmer while held
|
|
|
|
|
* then reverse direction
|
|
|
|
|
* Hold for hold time Released Off Any Power on at bri preset low
|
|
|
|
|
* Hold while Press & release up Any Any Toggle/change options
|
|
|
|
|
* Hold while Press & release down Any Any Toggle/change options
|
|
|
|
|
* Hold while Press up On Yes Brighter
|
|
|
|
|
* Hold while Press down On Yes Dimmer
|
|
|
|
|
* Released Hold up On No Brigther
|
|
|
|
|
* Released Hold down On No Dimmer
|
|
|
|
|
* Released Press & release up Off No Power on at bri preset low
|
|
|
|
|
* Released Press & release down Off No Power on at bri preset high
|
|
|
|
|
*
|
|
|
|
|
* Holding any button for over 10 seconds executes the WiFiConfig 2 command.
|
|
|
|
|
*
|
|
|
|
|
* In remote mode, whichever button is pressed first becomes the power button and any buttons
|
|
|
|
|
* pressed while it is held affect the device associated with it. The up and down buttons change
|
|
|
|
|
* depeneding on which button is the current power button:
|
|
|
|
|
*
|
|
|
|
|
* Power Down Up
|
|
|
|
|
* ----- ---- --
|
|
|
|
|
* 1 2 3
|
|
|
|
|
* 2 1 3
|
|
|
|
|
* 3 1 2
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// If the button is not pressed and was not just released (the most common case), just return.
|
|
|
|
|
if (XdrvMailbox.payload && !button_pressed[XdrvMailbox.index]) return;
|
|
|
|
|
|
|
|
|
|
bool handle_tap = false;
|
|
|
|
|
bool state_updated = false;
|
|
|
|
|
int32_t bri_offset = 0;
|
|
|
|
@ -290,260 +269,208 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
uint8_t dgr_value = 0;
|
|
|
|
|
uint8_t dgr_more_to_come = true;
|
|
|
|
|
uint8_t mqtt_trigger = 0;
|
|
|
|
|
uint32_t button_index = XdrvMailbox.index;
|
|
|
|
|
uint32_t now = millis();
|
|
|
|
|
|
|
|
|
|
// Initialize some variables.
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
bool power_is_on = (!active_device_is_local ? active_remote_pwm_dimmer->power_on : power);
|
|
|
|
|
bool power_is_on = (active_remote_pwm_dimmer ? active_remote_pwm_dimmer->power_on : power);
|
|
|
|
|
bool is_power_button = (button_index == power_button_index);
|
|
|
|
|
bool is_down_button = (button_index == down_button_index);
|
|
|
|
|
#else // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
bool power_is_on = power;
|
|
|
|
|
bool is_power_button = !button_index;
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
bool is_down_button = (button_index == (power_button_index ? 0 : 1));
|
|
|
|
|
|
|
|
|
|
// If the button is pressed, ...
|
|
|
|
|
if (!XdrvMailbox.payload) {
|
|
|
|
|
|
|
|
|
|
// If the button was just pressed, flag the button as pressed, clear the hold sent flag and
|
|
|
|
|
// increment the buttons pressed count.
|
|
|
|
|
if (!button_pressed[button_index]) {
|
|
|
|
|
button_pressed[button_index] = true;
|
|
|
|
|
button_hold_time[button_index] = now + Settings.param[P_HOLD_TIME] * 100;
|
|
|
|
|
buttons_pressed++;
|
|
|
|
|
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
// If there are no other buttons pressed right now and remote mode is enabled, make the device
|
|
|
|
|
// associated with this button the device we're going to control.
|
|
|
|
|
if (buttons_pressed == 1 && Settings.flag4.multiple_device_groups) {
|
|
|
|
|
power_button_index = button_index;
|
|
|
|
|
active_device_is_local = device_groups[power_button_index].local;
|
|
|
|
|
if (!active_device_is_local) active_remote_pwm_dimmer = &remote_pwm_dimmers[power_button_index - 1];
|
|
|
|
|
}
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
// If the button is being held, ...
|
|
|
|
|
if (pressed) {
|
|
|
|
|
uint32_t now = millis();
|
|
|
|
|
|
|
|
|
|
// If this is about the power button, ...
|
|
|
|
|
if (is_power_button) {
|
|
|
|
|
|
|
|
|
|
// If we're not ignoring the power button and no other buttons are pressed, ...
|
|
|
|
|
if (!ignore_power_button && buttons_pressed == 1) {
|
|
|
|
|
|
|
|
|
|
// If the power is on, adjust the brightness. Set the direction based on the current
|
|
|
|
|
// direction for the device and then invert the direction when the power button is released.
|
|
|
|
|
// The new brightness will be calculated below.
|
|
|
|
|
if (power_is_on) {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
bri_offset = (active_remote_pwm_dimmer ? (active_remote_pwm_dimmer->power_button_increases_bri ? 1 : -1) : (power_button_increases_bri ? 1 : -1));
|
|
|
|
|
#else // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
bri_offset = (power_button_increases_bri ? 1 : -1);
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
invert_power_button_bri_direction = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power is not on, turn it on using an initial brightness of bri_preset_low and set
|
|
|
|
|
// the power button hold time to delay before we start increasing the brightness.
|
|
|
|
|
else {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (active_remote_pwm_dimmer)
|
|
|
|
|
power_on_bri = active_remote_pwm_dimmer->bri = active_remote_pwm_dimmer->bri_preset_low;
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
power_on_bri = Settings.bri_preset_low;
|
|
|
|
|
button_hold_time[button_index] = now + 500;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the button is being held, ...
|
|
|
|
|
if (button_hold_time[button_index] < now) {
|
|
|
|
|
// If this is about the down or up buttons, ...
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
// If we're not in the middle of a power button plus up/down button sequence and the button
|
|
|
|
|
// has been held for over 10 seconds, execute the WiFiConfig 2 command.
|
|
|
|
|
if (!ignore_power_button && now - button_hold_time[button_index] > 10000) {
|
|
|
|
|
button_hold_time[button_index] = now + 90000;
|
|
|
|
|
char scmnd[20];
|
|
|
|
|
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_WIFICONFIG " 2"));
|
|
|
|
|
ExecuteCommand(scmnd, SRC_BUTTON);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// If the power button is also pressed, ...
|
|
|
|
|
if (button_pressed[power_button_index]) {
|
|
|
|
|
|
|
|
|
|
// Send a button hold if we haven't already. If it is handled (by the button topic or by a
|
|
|
|
|
// rule), ignore the this button until it's released.
|
|
|
|
|
if (!button_hold_sent[button_index]) {
|
|
|
|
|
button_hold_sent[button_index] = true;
|
|
|
|
|
button_hold_processed[button_index] = (!is_power_button && button_tapped ? false : SendKey(KEY_BUTTON, button_index + 1, POWER_HOLD));
|
|
|
|
|
}
|
|
|
|
|
if (!button_hold_processed[button_index]) {
|
|
|
|
|
|
|
|
|
|
// If this is about the power button, ...
|
|
|
|
|
if (is_power_button) {
|
|
|
|
|
|
|
|
|
|
// If we're not ignoring the power button and no other buttons are pressed, ...
|
|
|
|
|
if (!ignore_power_button && buttons_pressed == 1) {
|
|
|
|
|
|
|
|
|
|
// If the power is on, adjust the brightness. Set the direction based on the current
|
|
|
|
|
// direction for the device and then invert the direction when the power button is
|
|
|
|
|
// released. The new brightness will be calculated below.
|
|
|
|
|
if (power_is_on) {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
bri_offset = (!active_device_is_local ? (active_remote_pwm_dimmer->power_button_increases_bri ? 1 : -1) : (power_button_increases_bri ? 1 : -1));
|
|
|
|
|
#else // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
bri_offset = (power_button_increases_bri ? 1 : -1);
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
invert_power_button_bri_direction = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power is not on, turn it on using an initial brightness of bri_preset_low and
|
|
|
|
|
// set the power button hold time to delay before we start increasing the brightness.
|
|
|
|
|
else {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local)
|
|
|
|
|
power_on_bri = active_remote_pwm_dimmer->bri = active_remote_pwm_dimmer->bri_preset_low;
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
power_on_bri = Settings.bri_preset_low;
|
|
|
|
|
button_hold_time[button_index] = now + 500;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// If the up or down button was tapped while holding the power button before this, handle
|
|
|
|
|
// the operation below.
|
|
|
|
|
if (button_tapped) {
|
|
|
|
|
handle_tap = true;
|
|
|
|
|
button_hold_time[button_index] = now + 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If this is about the down or up buttons, ...
|
|
|
|
|
// Otherwise, if the power is on and remote mode is enabled, adjust the brightness. Set the
|
|
|
|
|
// direction based on which button is pressed. The new brightness will be calculated below.
|
|
|
|
|
else if (power_is_on && Settings.flag4.multiple_device_groups) {
|
|
|
|
|
bri_offset = (is_down_button ? -1 : 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, publish MQTT Event Trigger#.
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
// If the power button is also pressed, ...
|
|
|
|
|
if (button_pressed[power_button_index]) {
|
|
|
|
|
|
|
|
|
|
// If the up or down button was tapped while holding the power button before this,
|
|
|
|
|
// handle the operation below.
|
|
|
|
|
if (button_tapped) {
|
|
|
|
|
handle_tap = true;
|
|
|
|
|
button_hold_time[button_index] = now + 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, publish MQTT Event Trigger#.
|
|
|
|
|
else {
|
|
|
|
|
mqtt_trigger = (is_down_button ? 1 : 2);
|
|
|
|
|
button_hold_time[button_index] = now + 60000;
|
|
|
|
|
ignore_power_button = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, if the power is on, adjust the brightness. Set the direction based on which
|
|
|
|
|
// button is pressed. The new brightness will be calculated below.
|
|
|
|
|
else if (power_is_on && !button_tapped) {
|
|
|
|
|
bri_offset = (is_down_button ? -1 : 1);
|
|
|
|
|
}
|
|
|
|
|
mqtt_trigger = (is_down_button ? 1 : 2);
|
|
|
|
|
button_hold_time[button_index] = now + 60000;
|
|
|
|
|
ignore_power_button = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, if the power is on, adjust the brightness. Set the direction based on which
|
|
|
|
|
// button is pressed. The new brightness will be calculated below.
|
|
|
|
|
else if (power_is_on && !button_tapped) {
|
|
|
|
|
bri_offset = (is_down_button ? -1 : 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the button was just released, ...
|
|
|
|
|
else {
|
|
|
|
|
bool button_was_held = button_hold_sent[button_index];
|
|
|
|
|
button_hold_sent[button_index] = false;
|
|
|
|
|
bool button_was_held = button_held[button_index];
|
|
|
|
|
|
|
|
|
|
// If the button was not held, send a button toggle. If the button was held but not processes by
|
|
|
|
|
// support_button or support_buttondoesn't process the toggle (is not handled by a rule), ...
|
|
|
|
|
if (!(button_was_held ? button_hold_processed[button_index] : SendKey(KEY_BUTTON, button_index + 1, POWER_TOGGLE))) {
|
|
|
|
|
// If this is about the power button, ...
|
|
|
|
|
if (is_power_button) {
|
|
|
|
|
|
|
|
|
|
// If this is about the power button, ...
|
|
|
|
|
if (is_power_button) {
|
|
|
|
|
|
|
|
|
|
// If the up or down button was tapped while the power button was held and the up or
|
|
|
|
|
// down buttons weren't tapped or held afterwards, handle the operation based on which
|
|
|
|
|
// button was tapped.
|
|
|
|
|
if (button_tapped) {
|
|
|
|
|
if (!tap_handled) {
|
|
|
|
|
// If the up or down button was tapped while the power button was held and the up or down
|
|
|
|
|
// buttons weren't tapped or held afterwards, handle the operation based on which button was
|
|
|
|
|
// tapped.
|
|
|
|
|
if (button_tapped) {
|
|
|
|
|
if (!tap_handled) {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (active_device_is_local) {
|
|
|
|
|
if (!active_remote_pwm_dimmer) {
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
|
|
|
|
|
// Toggle the powered-off LED option.
|
|
|
|
|
if (down_button_tapped) {
|
|
|
|
|
Settings.flag4.led_timeout ^= 1;
|
|
|
|
|
if (Light.power) PWMDimmerSetBrightnessLeds(Settings.flag4.led_timeout ? 0 : -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Toggle the LED timeout.
|
|
|
|
|
else {
|
|
|
|
|
Settings.flag4.powered_off_led ^= 1;
|
|
|
|
|
PWMDimmerSetPoweredOffLed();
|
|
|
|
|
}
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
// Toggle the powered-off LED option.
|
|
|
|
|
if (down_button_tapped) {
|
|
|
|
|
Settings.flag4.led_timeout ^= 1;
|
|
|
|
|
if (Light.power) PWMDimmerSetBrightnessLeds(Settings.flag4.led_timeout ? 0 : -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Toggle the LED timeout.
|
|
|
|
|
else {
|
|
|
|
|
Settings.flag4.powered_off_led ^= 1;
|
|
|
|
|
PWMDimmerSetPoweredOffLed();
|
|
|
|
|
}
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
}
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
}
|
|
|
|
|
tap_handled = false;
|
|
|
|
|
}
|
|
|
|
|
tap_handled = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, if the power button was held, ...
|
|
|
|
|
else if (button_was_held) {
|
|
|
|
|
// Otherwise, if the power button was held, ...
|
|
|
|
|
else if (button_was_held) {
|
|
|
|
|
|
|
|
|
|
// If the power button was held with no other buttons pressed, we changed the brightness
|
|
|
|
|
// so invert the bri direction for the next time and send a final update.
|
|
|
|
|
if (invert_power_button_bri_direction) {
|
|
|
|
|
invert_power_button_bri_direction = false;
|
|
|
|
|
// If the power button was held with no other buttons pressed, we changed the brightness
|
|
|
|
|
// so invert the bri direction for the next time and send a final update.
|
|
|
|
|
if (invert_power_button_bri_direction) {
|
|
|
|
|
invert_power_button_bri_direction = false;
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local)
|
|
|
|
|
active_remote_pwm_dimmer->power_button_increases_bri ^= 1;
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
power_button_increases_bri ^= 1;
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
dgr_item = DGR_ITEM_FLAGS;
|
|
|
|
|
state_updated = true;
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power button was not held and we're not ignoring the next power button release,
|
|
|
|
|
// toggle the power.
|
|
|
|
|
else if (!ignore_power_button) {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local)
|
|
|
|
|
power_on_bri = active_remote_pwm_dimmer->bri_power_on;
|
|
|
|
|
if (active_remote_pwm_dimmer)
|
|
|
|
|
active_remote_pwm_dimmer->power_button_increases_bri ^= 1;
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
power_on_bri = Settings.bri_power_on;
|
|
|
|
|
power_button_increases_bri ^= 1;
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
dgr_item = DGR_ITEM_FLAGS;
|
|
|
|
|
state_updated = true;
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If this is about the up or down buttons, ...
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
// If the power button is also pressed, set the flag to ignore the power button until it is
|
|
|
|
|
// released.
|
|
|
|
|
if (button_pressed[power_button_index]) {
|
|
|
|
|
ignore_power_button = true;
|
|
|
|
|
|
|
|
|
|
// If the button was tapped, handle it below.
|
|
|
|
|
if (button_tapped) {
|
|
|
|
|
handle_tap = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, if the button was not held, flag the tap.
|
|
|
|
|
else if (!button_was_held) {
|
|
|
|
|
button_tapped = true;
|
|
|
|
|
down_button_tapped = is_down_button;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power button is not also pressed, ...
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
// If the power is on, ...
|
|
|
|
|
if (power_is_on) {
|
|
|
|
|
|
|
|
|
|
// If the button was not held, adjust the brightness. Set the direction based on which
|
|
|
|
|
// button is pressed. The new brightness will be calculated below.
|
|
|
|
|
if (!button_was_held) {
|
|
|
|
|
bri_offset = (is_down_button ? -1 : 1);
|
|
|
|
|
dgr_more_to_come = false;
|
|
|
|
|
state_updated = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the button was held and the hold was not processed by a rule, we changed the
|
|
|
|
|
// brightness and sent updates with the more-to-come message type while the button was
|
|
|
|
|
// held. Send a final update.
|
|
|
|
|
else if (!button_hold_processed[button_index]) {
|
|
|
|
|
dgr_item = DGR_ITEM_FLAGS;
|
|
|
|
|
state_updated = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power is off, turn it on using a temporary brightness of bri_preset_low if the
|
|
|
|
|
// down button is pressed or bri_preset_low if the up button is pressed.
|
|
|
|
|
else {
|
|
|
|
|
// If the power button was not held and we're not ignoring the next power button release,
|
|
|
|
|
// toggle the power.
|
|
|
|
|
else if (!ignore_power_button) {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local)
|
|
|
|
|
power_on_bri = active_remote_pwm_dimmer->bri = (is_down_button ? active_remote_pwm_dimmer->bri_preset_low : active_remote_pwm_dimmer->bri_preset_high);
|
|
|
|
|
else
|
|
|
|
|
if (active_remote_pwm_dimmer)
|
|
|
|
|
power_on_bri = active_remote_pwm_dimmer->bri_power_on;
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
power_on_bri = (is_down_button ? Settings.bri_preset_low : Settings.bri_preset_high);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
power_on_bri = Settings.bri_power_on;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flag the button as released.
|
|
|
|
|
button_pressed[button_index] = false;
|
|
|
|
|
buttons_pressed--;
|
|
|
|
|
if (is_power_button) {
|
|
|
|
|
ignore_power_button = false;
|
|
|
|
|
button_tapped = false;
|
|
|
|
|
// If this is about the up or down buttons, ...
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
// If the power button is also pressed, set the flag to ignore the power button until it is
|
|
|
|
|
// released.
|
|
|
|
|
if (button_pressed[power_button_index]) {
|
|
|
|
|
ignore_power_button = true;
|
|
|
|
|
|
|
|
|
|
// If the button was tapped, handle it below.
|
|
|
|
|
if (button_tapped) {
|
|
|
|
|
handle_tap = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, if the button was not held, flag the tap.
|
|
|
|
|
else if (!button_was_held) {
|
|
|
|
|
button_tapped = true;
|
|
|
|
|
down_button_tapped = is_down_button;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power button is not also pressed, ...
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
// If the power is on, ...
|
|
|
|
|
if (power_is_on) {
|
|
|
|
|
|
|
|
|
|
// If the button was not held, adjust the brightness. Set the direction based on which
|
|
|
|
|
// button is pressed. The new brightness will be calculated below.
|
|
|
|
|
if (!button_was_held) {
|
|
|
|
|
bri_offset = (is_down_button ? -5 : 5);
|
|
|
|
|
dgr_more_to_come = false;
|
|
|
|
|
state_updated = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the button was held, we changed the brightness and sent updates with the
|
|
|
|
|
// more-to-come message type while the button was held. Send a final update.
|
|
|
|
|
else {
|
|
|
|
|
dgr_item = DGR_ITEM_FLAGS;
|
|
|
|
|
state_updated = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power is off, turn it on using a temporary brightness of bri_preset_low if the
|
|
|
|
|
// down button is pressed or bri_preset_low if the up button is pressed.
|
|
|
|
|
else {
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (active_remote_pwm_dimmer)
|
|
|
|
|
power_on_bri = active_remote_pwm_dimmer->bri = (is_down_button ? active_remote_pwm_dimmer->bri_preset_low : active_remote_pwm_dimmer->bri_preset_high);
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
power_on_bri = (is_down_button ? Settings.bri_preset_low : Settings.bri_preset_high);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -551,7 +478,7 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
if (bri_offset) {
|
|
|
|
|
int32_t bri;
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local)
|
|
|
|
|
if (active_remote_pwm_dimmer)
|
|
|
|
|
bri = active_remote_pwm_dimmer->bri;
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
@ -569,7 +496,7 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
SendDeviceGroupMessage(power_button_index, (dgr_more_to_come ? DGR_MSGTYP_UPDATE_MORE_TO_COME : DGR_MSGTYP_UPDATE), DGR_ITEM_LIGHT_BRI, new_bri);
|
|
|
|
|
#endif // USE_DEVICE_GROUPS
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local) {
|
|
|
|
|
if (active_remote_pwm_dimmer) {
|
|
|
|
|
active_remote_pwm_dimmer->bri_power_on = active_remote_pwm_dimmer->bri = new_bri;
|
|
|
|
|
PWMDimmerSetBrightnessLeds(new_bri);
|
|
|
|
|
}
|
|
|
|
@ -591,7 +518,7 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
}
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
else if (!active_device_is_local)
|
|
|
|
|
else if (active_remote_pwm_dimmer)
|
|
|
|
|
PWMDimmerSetBrightnessLeds(new_bri);
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
else
|
|
|
|
@ -603,7 +530,7 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
power_t new_power;
|
|
|
|
|
#ifdef USE_DEVICE_GROUPS
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local) {
|
|
|
|
|
if (active_remote_pwm_dimmer) {
|
|
|
|
|
active_remote_pwm_dimmer->power_on ^= 1;
|
|
|
|
|
new_power = active_remote_pwm_dimmer->power_on;
|
|
|
|
|
PWMDimmerSetBrightnessLeds(new_power ? -power_on_bri : 0);
|
|
|
|
@ -621,7 +548,7 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
#endif // USE_DEVICE_GROUPS
|
|
|
|
|
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local)
|
|
|
|
|
if (active_remote_pwm_dimmer)
|
|
|
|
|
active_remote_pwm_dimmer->power_button_increases_bri = (power_on_bri < 128);
|
|
|
|
|
else {
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
@ -649,7 +576,7 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
#ifdef USE_DEVICE_GROUPS
|
|
|
|
|
int8_t add_value = (is_down_button ? -1 : 1);
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local) {
|
|
|
|
|
if (active_remote_pwm_dimmer) {
|
|
|
|
|
active_remote_pwm_dimmer->fixed_color_index += add_value;
|
|
|
|
|
dgr_value = active_remote_pwm_dimmer->fixed_color_index;
|
|
|
|
|
}
|
|
|
|
@ -675,35 +602,39 @@ void PWMDimmerHandleButton(void)
|
|
|
|
|
char topic[TOPSZ];
|
|
|
|
|
sprintf_P(mqtt_data, PSTR("Trigger%u"), mqtt_trigger);
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (!active_device_is_local) {
|
|
|
|
|
snprintf_P(topic, sizeof(topic), PSTR("cmnd/%s/Event"), device_groups[power_button_index].group_name);
|
|
|
|
|
if (active_remote_pwm_dimmer) {
|
|
|
|
|
snprintf_P(topic, sizeof(topic), PSTR("cmnd/%s/EVENT"), device_groups[power_button_index].group_name);
|
|
|
|
|
MqttPublish(topic);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
MqttPublishPrefixTopic_P(CMND, PSTR("Event"));
|
|
|
|
|
MqttPublishPrefixTopic_P(CMND, PSTR("EVENT"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we're not changing the brightness or toggling the power and we made changes, send a group
|
|
|
|
|
// update.
|
|
|
|
|
// If we need to send a device group update, do it.
|
|
|
|
|
if (dgr_item) {
|
|
|
|
|
#ifdef USE_DEVICE_GROUPS
|
|
|
|
|
DevGroupMessageType message_type = DGR_MSGTYP_UPDATE_DIRECT;
|
|
|
|
|
if (handle_tap && active_device_is_local) message_type = (DevGroupMessageType)(message_type + DGR_MSGTYPFLAG_WITH_LOCAL);
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (handle_tap && !active_remote_pwm_dimmer)
|
|
|
|
|
#else // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (handle_tap)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
message_type = (DevGroupMessageType)(message_type + DGR_MSGTYPFLAG_WITH_LOCAL);
|
|
|
|
|
SendDeviceGroupMessage(power_button_index, message_type, dgr_item, dgr_value);
|
|
|
|
|
#endif // USE_DEVICE_GROUPS
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (active_device_is_local)
|
|
|
|
|
if (!active_remote_pwm_dimmer)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
light_controller.saveSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state_updated)
|
|
|
|
|
if (state_updated && Settings.flag3.hass_tele_on_power) { // SetOption59 - Send tele/%topic%/STATE in addition to stat/%topic%/RESULT
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (active_device_is_local)
|
|
|
|
|
if (!active_remote_pwm_dimmer)
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
if (Settings.flag3.hass_tele_on_power) // SetOption59 - Send tele/%topic%/STATE in addition to stat/%topic%/RESULT
|
|
|
|
|
MqttPublishTeleState();
|
|
|
|
|
MqttPublishTeleState();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************************\
|
|
|
|
@ -796,8 +727,92 @@ bool Xdrv35(uint8_t function)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FUNC_BUTTON_PRESSED:
|
|
|
|
|
PWMDimmerHandleButton();
|
|
|
|
|
result = true;
|
|
|
|
|
// If the button is pressed or was just released, ...
|
|
|
|
|
if (!XdrvMailbox.payload || button_pressed[XdrvMailbox.index]) {
|
|
|
|
|
uint32_t button_index = XdrvMailbox.index;
|
|
|
|
|
uint32_t now = millis();
|
|
|
|
|
|
|
|
|
|
// If the button is pressed, ...
|
|
|
|
|
if (!XdrvMailbox.payload) {
|
|
|
|
|
|
|
|
|
|
// If the button was just pressed, flag the button as pressed, set the hold time and
|
|
|
|
|
// increment the buttons pressed count.
|
|
|
|
|
if (!button_pressed[button_index]) {
|
|
|
|
|
button_pressed[button_index] = true;
|
|
|
|
|
button_hold_time[button_index] = now + (button_index == power_button_index ? 500 : 250);
|
|
|
|
|
buttons_pressed++;
|
|
|
|
|
if (buttons_pressed > 1) multibutton_in_progress = true;
|
|
|
|
|
|
|
|
|
|
#ifdef USE_PWM_DIMMER_REMOTE
|
|
|
|
|
// If there are no other buttons pressed right now and remote mode is enabled, make the
|
|
|
|
|
// device associated with this button the device we're going to control. In remote mode,
|
|
|
|
|
// whichever button is pressed first becomes the power button and any buttons pressed
|
|
|
|
|
// while it is held affect the device associated with it. The up and down buttons change
|
|
|
|
|
// depeneding on which button is the current power button and are based on the GPIOs
|
|
|
|
|
// used on the MJ-SD01 type dimmers.
|
|
|
|
|
//
|
|
|
|
|
// Power Down Up
|
|
|
|
|
// Position GPIO Button GPIO GPIO
|
|
|
|
|
// -------- ---- ------ ---- ----
|
|
|
|
|
// Top 0 1 1 0
|
|
|
|
|
// Middle 1 2 15 0
|
|
|
|
|
// Bottom 15 3 15 1
|
|
|
|
|
if (buttons_pressed == 1 && Settings.flag4.multiple_device_groups) {
|
|
|
|
|
power_button_index = button_index;
|
|
|
|
|
down_button_index = (Pin(GPIO_KEY1, power_button_index) == 15 ? gpio_pin[1] : gpio_pin[15]) - 32;
|
|
|
|
|
active_remote_pwm_dimmer = nullptr;
|
|
|
|
|
if (power_button_index || !first_device_group_is_local)
|
|
|
|
|
active_remote_pwm_dimmer = &remote_pwm_dimmers[power_button_index];
|
|
|
|
|
}
|
|
|
|
|
#endif // USE_PWM_DIMMER_REMOTE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If hold time has arrived, handle it.
|
|
|
|
|
else if (button_hold_time[button_index] <= now) {
|
|
|
|
|
PWMDimmerHandleButton(button_index, true);
|
|
|
|
|
button_held[button_index] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the button was just released, flag the button as released and decrement the buttons
|
|
|
|
|
// pressed count.
|
|
|
|
|
else {
|
|
|
|
|
button_pressed[button_index] = false;
|
|
|
|
|
buttons_pressed--;
|
|
|
|
|
|
|
|
|
|
// If this is a multibutton press or the button was held, handle it.
|
|
|
|
|
if (multibutton_in_progress || button_held[button_index]) {
|
|
|
|
|
PWMDimmerHandleButton(button_index, false);
|
|
|
|
|
|
|
|
|
|
// Set a timer so FUNC_ANY_KEY ignores the button if support_button winds up sending a
|
|
|
|
|
// key because of this.
|
|
|
|
|
ignore_any_key_time = now + 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the power button was just released, clear the flags associated with it.
|
|
|
|
|
if (button_index == power_button_index) {
|
|
|
|
|
if (ignore_power_button) ignore_any_key_time = now + 500;
|
|
|
|
|
ignore_power_button = false;
|
|
|
|
|
button_tapped = false;
|
|
|
|
|
}
|
|
|
|
|
button_held[button_index] = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If a multi-button operation is in progress, tell support_button that we've handled it.
|
|
|
|
|
if (multibutton_in_progress) {
|
|
|
|
|
result = true;
|
|
|
|
|
if (buttons_pressed == 0) multibutton_in_progress = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FUNC_ANY_KEY:
|
|
|
|
|
{
|
|
|
|
|
uint32_t state = (XdrvMailbox.payload >> 8) & 0xFF; // 0 = Off, 1 = On, 2 = Toggle, 3 = Hold, 10,11,12,13 and 14 for Button Multipress
|
|
|
|
|
if ((state == 2 || state == 10) && ignore_any_key_time < millis()) {
|
|
|
|
|
PWMDimmerHandleButton((XdrvMailbox.payload & 0xFF) - 1, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#ifdef USE_DEVICE_GROUPS
|
|
|
|
|