mirror of https://github.com/arendst/Tasmota.git
Shutter continuous improvement (#18701)
* Update xdrv_27_esp32_shutter.ino * Update xdrv_27_shutter.ino * Update xdrv_01_9_webserver.ino * Update xdrv_12_discovery.ino * shutterinvert removed slider display to driver fix wrong invert display * codereduction+refactor slider removed webui slider into driver optimized code * update slide, fix invert shutters - refactor sliders into driver - fix percent calculation on iverted shutters * fix on realpercent if inverted shutter * fix ShutterPercentToRealPosition fix on inverted shutter * added shutter to bootloop reset * bugfix integration * bugfix
This commit is contained in:
parent
d5ad79985b
commit
a76ebaae48
|
@ -578,6 +578,7 @@ void setup(void) {
|
|||
}
|
||||
if (RtcReboot.fast_reboot_count > Settings->param[P_BOOT_LOOP_OFFSET] +2) { // Restarted 4 times
|
||||
Settings->rule_enabled = 0; // Disable all rules
|
||||
Settings->flag3.shutter_mode = 0; // disable shutter support
|
||||
TasmotaGlobal.no_autoexec = true;
|
||||
}
|
||||
if (RtcReboot.fast_reboot_count > Settings->param[P_BOOT_LOOP_OFFSET] +3) { // Restarted 5 times
|
||||
|
|
|
@ -264,9 +264,6 @@ const char HTTP_MSG_SLIDER_GRADIENT[] PROGMEM =
|
|||
"<div id='%s' class='r' style='background-image:linear-gradient(to right,%s,%s);'>"
|
||||
"<input id='sl%d' type='range' min='%d' max='%d' value='%d' onchange='lc(\"%c\",%d,value)'>"
|
||||
"</div>";
|
||||
const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM =
|
||||
"<div><span class='p'>" D_CLOSE "</span><span class='q'>" D_OPEN "</span></div>"
|
||||
"<div><input type='range' min='0' max='100' value='%d' onchange='lc(\"u\",%d,value)'></div>";
|
||||
|
||||
const char HTTP_MSG_RSTRT[] PROGMEM =
|
||||
"<br><div style='text-align:center;'>" D_DEVICE_WILL_RESTART "</div><br>";
|
||||
|
@ -1229,13 +1226,6 @@ void HandleRoot(void)
|
|||
} // Settings->flag3.pwm_multi_channels
|
||||
}
|
||||
#endif // USE_LIGHT
|
||||
#ifdef USE_SHUTTER
|
||||
if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
WSContentSend_P(HTTP_MSG_SLIDER_SHUTTER, ShutterRealToPercentPosition(-9999, i), i+1);
|
||||
}
|
||||
}
|
||||
#endif // USE_SHUTTER
|
||||
WSContentSend_P(HTTP_TABLE100);
|
||||
WSContentSend_P(PSTR("<tr>"));
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
|
@ -1258,7 +1248,7 @@ void HandleRoot(void)
|
|||
int32_t ShutterWebButton;
|
||||
if (ShutterWebButton = IsShutterWebButton(idx)) {
|
||||
WSContentSend_P(HTTP_DEVICE_CONTROL, 100 / cols, idx,
|
||||
(set_button) ? SettingsText(SET_BUTTON1 + idx -1) : ((Settings->shutter_options[abs(ShutterWebButton)-1] & 2) /* is locked */ ? "-" : ((Settings->shutter_options[abs(ShutterWebButton)-1] & 8) /* invert web buttons */ ? ((ShutterWebButton>0) ? "▼" : "▲") : ((ShutterWebButton>0) ? "▲" : "▼"))),
|
||||
(set_button) ? SettingsText(SET_BUTTON1 + idx -1) : ((ShutterGetOptions(abs(ShutterWebButton)-1) & 2) /* is locked */ ? "-" : ((Settings->shutter_options[abs(ShutterWebButton)-1] & 8) /* invert web buttons */ ? ((ShutterWebButton>0) ? "▼" : "▲") : ((ShutterWebButton>0) ? "▲" : "▼"))),
|
||||
"");
|
||||
} else {
|
||||
#endif // USE_SHUTTER
|
||||
|
@ -1410,10 +1400,12 @@ bool HandleRootStatusRefresh(void)
|
|||
#endif // USE_LIGHT
|
||||
#ifdef USE_SHUTTER
|
||||
for (uint32_t j = 1; j <= TasmotaGlobal.shutters_present; j++) {
|
||||
uint8_t percent;
|
||||
snprintf_P(webindex, sizeof(webindex), PSTR("u%d"), j);
|
||||
WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent
|
||||
percent = atoi(tmp);
|
||||
if (strlen(tmp)) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %s"), j, tmp);
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %d"), j, (ShutterGetOptions(j-1) & 1) ? 100 - percent : percent);
|
||||
ExecuteWebCommand(svalue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,9 +200,9 @@ void TasDiscoverMessage(void) {
|
|||
light_controller_isCTRGBLinked,
|
||||
light_subtype);
|
||||
|
||||
for (uint32_t i = 0; i < tmin(TasmotaGlobal.shutters_present, MAX_SHUTTERS); i++) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
#ifdef USE_SHUTTER
|
||||
ResponseAppend_P(PSTR("%s%d"), (i > 0 ? "," : ""), Settings->shutter_options[i]);
|
||||
ResponseAppend_P(PSTR("%s%d"), (i > 0 ? "," : ""), ShutterGetOptions(i));
|
||||
#else
|
||||
ResponseAppend_P(PSTR("%s0"), (i > 0 ? "," : ""));
|
||||
#endif // USE_SHUTTER
|
||||
|
@ -210,7 +210,7 @@ void TasDiscoverMessage(void) {
|
|||
|
||||
ResponseAppend_P(PSTR("]," // Shutter Options (end)
|
||||
"\"sht\":[")); // Shutter Tilt (start)
|
||||
for (uint32_t i = 0; i < tmax(TasmotaGlobal.shutters_present, MAX_SHUTTERS); i++) {
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
#ifdef USE_SHUTTER
|
||||
ResponseAppend_P(PSTR("%s[%d,%d,%d]"), (i > 0 ? "," : ""),
|
||||
ShutterGetTiltConfig(0,i),
|
||||
|
|
|
@ -54,7 +54,10 @@
|
|||
#define D_ERROR_FILESYSTEM_NOT_READY "SHT: ERROR File system not enabled"
|
||||
#define D_ERROR_FILE_NOT_FOUND "SHT: ERROR File system not ready or file not found"
|
||||
|
||||
//
|
||||
const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM =
|
||||
"<div><span class='p'>%s</span><span class='q'>%s</span></div>"
|
||||
"<div><input type='range' min='0' max='100' value='%d' onchange='lc(\"u\",%d,value)'></div>";
|
||||
|
||||
const uint32_t SHUTTER_VERSION = 0x01010100; // Latest driver version (See settings deltas below)
|
||||
|
||||
typedef struct { // depreciated 2023-04-28
|
||||
|
@ -364,7 +367,7 @@ bool ShutterStatus(void) {
|
|||
"\"Mode\":\"%d\","
|
||||
"\"TiltConfig\":[%d,%d,%d,%d,%d]}"),
|
||||
i, ShutterSettings.shutter_startrelay[i], ShutterSettings.shutter_startrelay[i] +1, ShutterSettings.shutter_opentime[i], ShutterSettings.shutter_closetime[i],
|
||||
ShutterSettings.shutter_set50percent[i], ShutterSettings.shutter_motordelay[i], GetBinary8(Settings->shutter_options[i], 4).c_str(),
|
||||
ShutterSettings.shutter_set50percent[i], ShutterSettings.shutter_motordelay[i], GetBinary8(ShutterSettings.shutter_options[i], 4).c_str(),
|
||||
ShutterSettings.shuttercoeff[0][i], ShutterSettings.shuttercoeff[1][i], ShutterSettings.shuttercoeff[2][i], ShutterSettings.shuttercoeff[3][i], ShutterSettings.shuttercoeff[4][i],
|
||||
ShutterSettings.shutter_mode,
|
||||
ShutterSettings.shutter_tilt_config[0][i], ShutterSettings.shutter_tilt_config[1][i], ShutterSettings.shutter_tilt_config[2][i], ShutterSettings.shutter_tilt_config[3][i], ShutterSettings.shutter_tilt_config[4][i]
|
||||
|
@ -389,6 +392,10 @@ uint8_t ShutterGetStartRelay(uint8_t index) {
|
|||
return ShutterSettings.shutter_startrelay[index];
|
||||
}
|
||||
|
||||
uint8_t ShutterGetOptions(uint8_t index) {
|
||||
return ShutterSettings.shutter_options[index];
|
||||
}
|
||||
|
||||
int8_t ShutterGetTiltConfig(uint8_t config_idx,uint8_t index) {
|
||||
return Shutter[index].tilt_config[config_idx];
|
||||
}
|
||||
|
@ -497,13 +504,13 @@ int32_t ShutterPercentToRealPosition(int16_t percent, uint32_t index)
|
|||
|
||||
uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index)
|
||||
{
|
||||
int64_t realpercent;
|
||||
if (realpos == -9999) {
|
||||
realpos = Shutter[index].real_position;
|
||||
}
|
||||
if (ShutterSettings.shutter_set50percent[index] != 50) {
|
||||
return (ShutterSettings.shuttercoeff[2][index] * 5 > realpos/10) ? SHT_DIV_ROUND(realpos/10, ShutterSettings.shuttercoeff[2][index]) : SHT_DIV_ROUND(realpos/10-ShutterSettings.shuttercoeff[0][index]*10, ShutterSettings.shuttercoeff[1][index]);
|
||||
realpercent = (ShutterSettings.shuttercoeff[2][index] * 5 > realpos/10) ? SHT_DIV_ROUND(realpos/10, ShutterSettings.shuttercoeff[2][index]) : SHT_DIV_ROUND(realpos/10-ShutterSettings.shuttercoeff[0][index]*10, ShutterSettings.shuttercoeff[1][index]);
|
||||
} else {
|
||||
int64_t realpercent;
|
||||
for (uint32_t j = 0; j < 5; j++) {
|
||||
if (realpos >= Shutter[index].open_max * calibrate_pos[j+1] / 100) {
|
||||
realpercent = SHT_DIV_ROUND(ShutterSettings.shuttercoeff[j][index], 10);
|
||||
|
@ -521,10 +528,10 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index)
|
|||
break;
|
||||
}
|
||||
}
|
||||
realpercent = realpercent < 0 ? 0 : realpercent;
|
||||
// if inverted recalculate the percentposition
|
||||
return (ShutterSettings.shutter_options[index] & 1) ? 100 - realpercent : realpercent;
|
||||
}
|
||||
realpercent = realpercent < 0 ? 0 : realpercent;
|
||||
// if inverted recalculate the percentposition
|
||||
return (ShutterSettings.shutter_options[index] & 1) ? 100 - realpercent : realpercent;
|
||||
}
|
||||
|
||||
void ShutterInit(void)
|
||||
|
@ -1127,8 +1134,8 @@ void ShutterRelayChanged(void)
|
|||
// powerstate_local == 1 => direction=1, target=Shutter[i].open_max
|
||||
// powerstate_local == 2 => direction=-1, target=0 // only happen on SHT_TIME
|
||||
// powerstate_local == 3 => direction=-1, target=0 // only happen if NOT SHT_TIME
|
||||
int direction = (powerstate_local == 0) ? 0 : (powerstate_local == 1) ? 1 : -1;
|
||||
int target = (powerstate_local == 1) ? Shutter[i].open_max : 0;
|
||||
int8_t direction = (powerstate_local == 0) ? 0 : (powerstate_local == 1) ? 1 : -1;
|
||||
int8_t target = (powerstate_local == 1) ? Shutter[i].open_max : 0;
|
||||
|
||||
if (direction != 0) {
|
||||
ShutterStartInit(i, direction, target);
|
||||
|
@ -1318,6 +1325,11 @@ void ShutterToggle(bool dir)
|
|||
}
|
||||
}
|
||||
|
||||
void ShutterShow(){
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
WSContentSend_P(HTTP_MSG_SLIDER_SHUTTER, (ShutterSettings.shutter_options[i] & 1) ? D_OPEN : D_CLOSE,(ShutterSettings.shutter_options[i] & 1) ? D_CLOSE : D_OPEN, ShutterRealToPercentPosition(-9999, i), i+1);
|
||||
}
|
||||
}
|
||||
/*********************************************************************************************\
|
||||
* Commands
|
||||
\*********************************************************************************************/
|
||||
|
@ -2328,6 +2340,11 @@ bool Xdrv27(uint32_t function)
|
|||
result = false;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_SENSOR:
|
||||
ShutterShow();
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -72,6 +72,10 @@ int32_t next_possible_stop_position = 0;
|
|||
int32_t current_real_position = 0;
|
||||
int32_t current_pwm_velocity = 0;
|
||||
|
||||
const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM =
|
||||
"<div><span class='p'>%s</span><span class='q'>%s</span></div>"
|
||||
"<div><input type='range' min='0' max='100' value='%d' onchange='lc(\"u\",%d,value)'></div>";
|
||||
|
||||
const uint8_t MAX_MODES = 8;
|
||||
enum Shutterposition_mode {SHT_UNDEF, SHT_TIME, SHT_TIME_UP_DOWN, SHT_TIME_GARAGE, SHT_COUNTER, SHT_PWM_VALUE, SHT_PWM_TIME,SHT_AUTOCONFIG};
|
||||
enum Shutterswitch_mode {SHT_SWITCH, SHT_PULSE,};
|
||||
|
@ -189,6 +193,10 @@ uint8_t ShutterGetStartRelay(uint8_t index) {
|
|||
return Settings->shutter_startrelay[index];
|
||||
}
|
||||
|
||||
uint8_t ShutterGetOptions(uint8_t index) {
|
||||
return Settings->shutter_options[index];
|
||||
}
|
||||
|
||||
int8_t ShutterGetTiltConfig(uint8_t config_idx,uint8_t index) {
|
||||
return Shutter[index].tilt_config[config_idx];
|
||||
}
|
||||
|
@ -259,6 +267,8 @@ void ShutterRtc50mS(void)
|
|||
|
||||
int32_t ShutterPercentToRealPosition(int16_t percent, uint32_t index)
|
||||
{
|
||||
// if inverted recalculate the percentposition
|
||||
percent = (Settings->shutter_options[index] & 1) ? 100 - percent : percent;
|
||||
if (Settings->shutter_set50percent[index] != 50) {
|
||||
return (percent <= 5) ? Settings->shuttercoeff[2][index] * percent*10 : (Settings->shuttercoeff[1][index] * percent + (Settings->shuttercoeff[0][index]*10))*10;
|
||||
} else {
|
||||
|
@ -295,13 +305,13 @@ int32_t ShutterPercentToRealPosition(int16_t percent, uint32_t index)
|
|||
|
||||
uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index)
|
||||
{
|
||||
int64_t realpercent;
|
||||
if (realpos == -9999) {
|
||||
realpos = Shutter[index].real_position;
|
||||
}
|
||||
if (Settings->shutter_set50percent[index] != 50) {
|
||||
return (Settings->shuttercoeff[2][index] * 5 > realpos/10) ? SHT_DIV_ROUND(realpos/10, Settings->shuttercoeff[2][index]) : SHT_DIV_ROUND(realpos/10-Settings->shuttercoeff[0][index]*10, Settings->shuttercoeff[1][index]);
|
||||
realpercent = (Settings->shuttercoeff[2][index] * 5 > realpos/10) ? SHT_DIV_ROUND(realpos/10, Settings->shuttercoeff[2][index]) : SHT_DIV_ROUND(realpos/10-Settings->shuttercoeff[0][index]*10, Settings->shuttercoeff[1][index]);
|
||||
} else {
|
||||
int64_t realpercent;
|
||||
for (uint32_t j = 0; j < 5; j++) {
|
||||
if (realpos >= Shutter[index].open_max * calibrate_pos[j+1] / 100) {
|
||||
realpercent = SHT_DIV_ROUND(Settings->shuttercoeff[j][index], 10);
|
||||
|
@ -319,8 +329,10 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index)
|
|||
break;
|
||||
}
|
||||
}
|
||||
return realpercent < 0 ? 0 : realpercent;
|
||||
}
|
||||
realpercent = realpercent < 0 ? 0 : realpercent;
|
||||
// if inverted recalculate the percentposition
|
||||
return (Settings->shutter_options[index] & 1) ? 100 - realpercent : realpercent;
|
||||
}
|
||||
|
||||
void ShutterInit(void)
|
||||
|
@ -876,52 +888,38 @@ void ShutterRelayChanged(void)
|
|||
Shutter[i].tiltmoving = 0;
|
||||
}
|
||||
switch (ShutterGlobal.position_mode) {
|
||||
// enum Shutterposition_mode {SHT_TIME, SHT_TIME_UP_DOWN, SHT_TIME_GARAGE, SHT_COUNTER, SHT_PWM_VALUE, SHT_PWM_TIME,};
|
||||
case SHT_TIME_UP_DOWN:
|
||||
case SHT_COUNTER:
|
||||
case SHT_PWM_VALUE:
|
||||
case SHT_PWM_TIME:
|
||||
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: power off manual change"));
|
||||
ShutterPowerOff(i);
|
||||
switch (powerstate_local) {
|
||||
case 1:
|
||||
ShutterStartInit(i, 1, Shutter[i].open_max);
|
||||
break;
|
||||
case 3:
|
||||
ShutterStartInit(i, -1, 0);
|
||||
break;
|
||||
default:
|
||||
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Switch OFF motor."),i);
|
||||
// enum Shutterposition_mode {SHT_TIME, SHT_TIME_UP_DOWN, SHT_TIME_GARAGE, SHT_COUNTER, SHT_PWM_VALUE, SHT_PWM_TIME,};
|
||||
case SHT_TIME_UP_DOWN:
|
||||
case SHT_COUNTER:
|
||||
case SHT_PWM_VALUE:
|
||||
case SHT_PWM_TIME:
|
||||
case SHT_TIME: {
|
||||
ShutterPowerOff(i);
|
||||
// powerstate_local == 0 => direction=0, stop
|
||||
// powerstate_local == 1 => direction=1, target=Shutter[i].open_max
|
||||
// powerstate_local == 2 => direction=-1, target=0 // only happen on SHT_TIME
|
||||
// powerstate_local == 3 => direction=-1, target=0 // only happen if NOT SHT_TIME
|
||||
int8_t direction = (powerstate_local == 0) ? 0 : (powerstate_local == 1) ? 1 : -1;
|
||||
int8_t target = (powerstate_local == 1) ? Shutter[i].open_max : 0;
|
||||
|
||||
if (direction != 0) {
|
||||
ShutterStartInit(i, direction, target);
|
||||
} else {
|
||||
Shutter[i].target_position = Shutter[i].real_position;
|
||||
Shutter[i].last_stop_time = millis();
|
||||
}
|
||||
break;
|
||||
case SHT_TIME:
|
||||
switch (powerstate_local) {
|
||||
case 1:
|
||||
ShutterStartInit(i, 1, Shutter[i].open_max);
|
||||
break;
|
||||
case 2:
|
||||
ShutterStartInit(i, -1, 0);
|
||||
break;
|
||||
default:
|
||||
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Switch OFF motor."),i+1);
|
||||
Shutter[i].target_position = Shutter[i].real_position;
|
||||
Shutter[i].last_stop_time = millis();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SHT_TIME_GARAGE:
|
||||
switch (powerstate_local) {
|
||||
case 1:
|
||||
ShutterStartInit(i, Shutter[i].lastdirection*-1 , Shutter[i].lastdirection == 1 ? 0 : Shutter[i].open_max);
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Garage. NewTarget %d"), i, Shutter[i].target_position);
|
||||
break;
|
||||
default:
|
||||
Shutter[i].target_position = Shutter[i].real_position;
|
||||
}
|
||||
|
||||
|
||||
} // switch (ShutterGlobal.position_mode)
|
||||
case SHT_TIME_GARAGE:
|
||||
switch (powerstate_local) {
|
||||
case 1:
|
||||
ShutterStartInit(i, Shutter[i].lastdirection * -1, Shutter[i].lastdirection == 1 ? 0 : Shutter[i].open_max);
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Garage. NewTarget %d"), i, Shutter[i].target_position);
|
||||
break;
|
||||
default:
|
||||
Shutter[i].target_position = Shutter[i].real_position;
|
||||
}
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Target %ld, Power: %d, tiltmv: %d"), i+1, Shutter[i].target_position, powerstate_local,Shutter[i].tiltmoving);
|
||||
} // if (manual_relays_changed)
|
||||
} // for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++)
|
||||
|
@ -940,11 +938,11 @@ bool ShutterButtonIsSimultaneousHold(uint32_t button_index, uint32_t shutter_ind
|
|||
|
||||
bool ShutterButtonHandler(void)
|
||||
{
|
||||
uint8_t buttonState = SHT_NOT_PRESSED;
|
||||
uint8_t button = XdrvMailbox.payload;
|
||||
uint8_t press_index;
|
||||
uint8_t buttonState = SHT_NOT_PRESSED;
|
||||
uint8_t button = XdrvMailbox.payload;
|
||||
uint8_t press_index;
|
||||
uint32_t button_index = XdrvMailbox.index;
|
||||
uint8_t shutter_index = Settings->shutter_button[button_index] & 0x03;
|
||||
uint8_t shutter_index = Settings->shutter_button[button_index] & 0x03;
|
||||
uint16_t loops_per_second = 1000 / Settings->button_debounce; // ButtonDebounce (50)
|
||||
|
||||
if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) {
|
||||
|
@ -976,8 +974,8 @@ bool ShutterButtonHandler(void)
|
|||
Button.hold_timer[button_index] = 0;
|
||||
} else {
|
||||
Button.hold_timer[button_index]++;
|
||||
if (!Settings->flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action
|
||||
if (Settings->param[P_HOLD_IGNORE] > 0) { // SetOption40 (0) - Do not ignore button hold
|
||||
if (!Settings->flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action
|
||||
if (Settings->param[P_HOLD_IGNORE] > 0) { // SetOption40 (0) - Do not ignore button hold
|
||||
if (Button.hold_timer[button_index] > loops_per_second * Settings->param[P_HOLD_IGNORE] / 10) {
|
||||
Button.hold_timer[button_index] = 0; // Reset button hold counter to stay below hold trigger
|
||||
Button.press_counter[button_index] = 0; // Discard button press to disable functionality
|
||||
|
@ -1159,6 +1157,12 @@ void ShutterToggle(bool dir)
|
|||
}
|
||||
}
|
||||
|
||||
void ShutterShow(){
|
||||
for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
WSContentSend_P(HTTP_MSG_SLIDER_SHUTTER, (Settings->shutter_options[i] & 1) ? D_OPEN : D_CLOSE,(Settings->shutter_options[i] & 1) ? D_CLOSE : D_OPEN, ShutterRealToPercentPosition(-9999, i), i+1);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Commands
|
||||
\*********************************************************************************************/
|
||||
|
@ -1980,6 +1984,11 @@ bool Xdrv27(uint32_t function)
|
|||
result = true;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_SENSOR:
|
||||
ShutterShow();
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
Loading…
Reference in New Issue