diff --git a/tasmota/i18n.h b/tasmota/i18n.h index c08703e0f..1b8115d28 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -694,6 +694,7 @@ #define D_CMND_SHUTTER_UNITTEST "UnitTest" #define D_CMND_SHUTTER_TILTCONFIG "TiltConfig" #define D_CMND_SHUTTER_SETTILT "Tilt" +#define D_CMND_SHUTTER_TILTINCDEC "TiltChange" // Commands xdrv_32_hotplug.ino #define D_CMND_HOTPLUG "HotPlug" diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index de3f20239..f7ddfb222 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -47,6 +47,7 @@ int32_t current_stop_way = 0; int32_t next_possible_stop_position = 0; int32_t current_real_position = 0; int32_t current_pwm_velocity = 0; +int8_t savedata_original = 0; const uint8_t MAX_MODES = 7; enum Shutterposition_mode {SHT_UNDEF, SHT_TIME, SHT_TIME_UP_DOWN, SHT_TIME_GARAGE, SHT_COUNTER, SHT_PWM_VALUE, SHT_PWM_TIME,}; @@ -59,7 +60,7 @@ const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|" D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_SETOPEN "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS "|" D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPTOGGLEDIR "|" D_CMND_SHUTTER_STOPPOSITION "|" D_CMND_SHUTTER_INCDEC "|" - D_CMND_SHUTTER_UNITTEST "|" D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|"; + D_CMND_SHUTTER_UNITTEST "|" D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC "|"; void (* const ShutterCommand[])(void) PROGMEM = { &CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterToggleDir, &CmndShutterStop, &CmndShutterPosition, @@ -67,7 +68,7 @@ void (* const ShutterCommand[])(void) PROGMEM = { &CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterSetOpen, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay, &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons, &CmndShutterStopOpen, &CmndShutterStopClose, &CmndShutterStopToggle, &CmndShutterStopToggleDir, &CmndShutterStopPosition, &CmndShutterIncDec, - &CmndShutterUnitTest,&CmndShutterTiltConfig,&CmndShutterSetTilt}; + &CmndShutterUnitTest,&CmndShutterTiltConfig,&CmndShutterSetTilt,&CmndShutterTiltIncDec}; const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d,\"Target\":%d,\"Tilt\":%d}"; const char JSON_SHUTTER_BUTTON[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Button%d\":%d}"; @@ -102,6 +103,7 @@ struct SHUTTER { uint16_t venetian_delay = 0; // Delay in steps before venetian shutter start physical moving. Based on tilt position uint16_t min_realPositionChange = 0; // minimum change of the position before the shutter operates. different for PWM and time based operations uint16_t min_TiltChange = 0; // minimum change of the tilt before the shutter operates. different for PWM and time based operations + uint16_t last_reported_time =0; } Shutter[MAX_SHUTTERS]; struct SHUTTERGLOBAL { @@ -326,8 +328,9 @@ void ShutterInit(void) for (uint8_t k=0; k<5; k++) { Shutter[i].tilt_config[k] = Settings->shutter_tilt_config[k][i]; } - Shutter[i].tilt_real_pos = Settings->shutter_tilt_pos[i]; - Shutter[i].tilt_velocity = Shutter[i].tilt_config[2] > 0 ? (Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0])/Shutter[i].tilt_config[2] : 1; + Shutter[i].tilt_target_pos = Shutter[i].tilt_real_pos = Settings->shutter_tilt_pos[i]; + + Shutter[i].tilt_velocity = Shutter[i].tilt_config[2] > 0 ? ((Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0])/Shutter[i].tilt_config[2])+1 : 1; Shutter[i].close_velocity_max = ShutterGlobal.open_velocity_max*Shutter[i].open_time / Shutter[i].close_time; @@ -345,7 +348,7 @@ void ShutterInit(void) break; } AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d min realpos_chg: %d, min tilt_chg %d"),i+1,Shutter[i].min_realPositionChange,Shutter[i].min_TiltChange); - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Openvel %d, Closevel: %d"),i, ShutterGlobal.open_velocity_max, Shutter[i].close_velocity_max); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Openvel %d, Closevel: %d"),i, ShutterGlobal.open_velocity_max, Shutter[i].close_velocity_max); AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Init. Pos %d, Inv %d, Locked %d, Endstop enab %d, webButt inv %d, Motordel: %d"), i+1, Shutter[i].real_position, (Settings->shutter_options[i]&1) ? 1 : 0, (Settings->shutter_options[i]&2) ? 1 : 0, (Settings->shutter_options[i]&4) ? 1 : 0, (Settings->shutter_options[i]&8) ? 1 : 0, Shutter[i].motordelay); @@ -362,9 +365,9 @@ void ShutterInit(void) void ShutterReportPosition(bool always, uint32_t index) { Response_P(PSTR("{")); - TasmotaGlobal.rules_flag.shutter_moving = 0; uint32_t i = 0; uint32_t n = TasmotaGlobal.shutters_present; + uint8_t shutter_running = 0; if( index != MAX_SHUTTERS) { i = index; n = index+1; @@ -373,15 +376,15 @@ void ShutterReportPosition(bool always, uint32_t index) //AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Real Pos %d"), i+1,Shutter[i].real_position); uint32_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); if (Shutter[i].direction != 0) { - TasmotaGlobal.rules_flag.shutter_moving = 1; ShutterLogPos(i); + shutter_running++; } if (i && index == MAX_SHUTTERS) { ResponseAppend_P(PSTR(",")); } uint32_t target = ShutterRealToPercentPosition(Shutter[i].target_position, i); ResponseAppend_P(JSON_SHUTTER_POS, i+1, (Settings->shutter_options[i] & 1) ? 100-position : position, Shutter[i].direction,(Settings->shutter_options[i] & 1) ? 100-target : target, Shutter[i].tilt_real_pos ); } ResponseJsonEnd(); - if (always || (TasmotaGlobal.rules_flag.shutter_moving)) { + if (always || shutter_running) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); // RulesProcess() now re-entry protected } //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), TasmotaGlobal.rules_flag.shutter_moving, TasmotaGlobal.rules_flag.shutter_moved); @@ -471,8 +474,12 @@ void ShutterDecellerateForStop(uint8_t i) void ShutterPowerOff(uint8_t i) { - AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Stop Shutter %d. Switchmode %d"), i+1,Shutter[i].switch_mode); // fix log to indicate correct shutter number + AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Stop %d. Mode %d, time:%d"), i+1,Shutter[i].switch_mode, Shutter[i].time); // fix log to indicate correct shutter number ShutterDecellerateForStop(i); + if (Shutter[i].direction !=0) { + Shutter[i].direction = 0; + } + TasmotaGlobal.rules_flag.shutter_moved = 1; switch (Shutter[i].switch_mode) { case SHT_SWITCH: if ((1 << (Settings->shutter_startrelay[i]-1)) & TasmotaGlobal.power) { @@ -512,10 +519,9 @@ void ShutterPowerOff(uint8_t i) ExecuteCommand(scmnd, SRC_BUTTON); break; } - if (Shutter[i].direction !=0) { - Shutter[i].direction = 0; - delay(MOTOR_STOP_TIME); - } + Settings->save_data = savedata_original; + TasmotaGlobal.save_data_counter = Settings->save_data; + delay(MOTOR_STOP_TIME); } void ShutterUpdatePosition(void) @@ -529,11 +535,12 @@ void ShutterUpdatePosition(void) XdrvRulesProcess(0); ShutterGlobal.start_reported = 1; } - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Time %d, cStop %d, cVelo %d, mVelo %d, aVelo %d, mRun %d, aPos %d, aPos2 %d, nStop %d, Trgt %d, mVelo %d, Dir %d, Tilt %d, TrgtTilt: %d, Tiltmove: %d"), - Shutter[i].time, current_stop_way, current_pwm_velocity, velocity_max, Shutter[i].accelerator, min_runtime_ms, current_real_position,Shutter[i].real_position, + int32_t deltatime = Shutter[i].time-Shutter[i].last_reported_time; + Shutter[i].last_reported_time = Shutter[i].time+1; + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Time %d(%d), cStop %d, cVelo %d, mVelo %d, aVelo %d, mRun %d, aPos %d, aPos2 %d, nStop %d, Trgt %d, mVelo %d, Dir %d, Tilt %d, TrgtTilt: %d, Tiltmove: %d"), + Shutter[i].time, deltatime, current_stop_way, current_pwm_velocity, velocity_max, Shutter[i].accelerator, min_runtime_ms, current_real_position,Shutter[i].real_position, next_possible_stop_position, Shutter[i].target_position, velocity_change_per_step_max, Shutter[i].direction,Shutter[i].tilt_real_pos, Shutter[i].tilt_target_pos, Shutter[i].tiltmoving); - if ( ((Shutter[i].real_position * Shutter[i].direction >= Shutter[i].target_position * Shutter[i].direction && Shutter[i].tiltmoving==0) || ((int16_t)Shutter[i].tilt_real_pos * Shutter[i].direction * Shutter[i].tilt_config[2] >= (int16_t)Shutter[i].tilt_target_pos * Shutter[i].direction * Shutter[i].tilt_config[2] && Shutter[i].tiltmoving==1)) || (ShutterGlobal.position_mode == SHT_COUNTER && Shutter[i].accelerator <0 && Shutter[i].pwm_velocity+Shutter[i].acceleratorshutter_position[i] == 0 ? Shutter[i].tilt_config[0] : Shutter[i].tilt_target_pos; Shutter[i].tilt_target_pos = Settings->shutter_position[i] == 100 ? Shutter[i].tilt_config[1] : Shutter[i].tilt_target_pos; - if (abs(Shutter[i].tilt_real_pos - Shutter[i].tilt_target_pos) > Shutter[i].min_TiltChange) { + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Pre: Tilt not match %d -> %d, moving: %d"),Shutter[i].tilt_real_pos,Shutter[i].tilt_target_pos,Shutter[i].tiltmoving); + if (abs(Shutter[i].tilt_real_pos - Shutter[i].tilt_target_pos) > Shutter[i].min_TiltChange && Shutter[i].tiltmoving == 0) { AddLog(LOG_LEVEL_INFO, PSTR("SHT: Tilt not match %d -> %d"),Shutter[i].tilt_real_pos,Shutter[i].tilt_target_pos); XdrvMailbox.payload = -99; XdrvMailbox.index = i+1; @@ -557,7 +565,6 @@ void ShutterUpdatePosition(void) return; } else { Settings->shutter_tilt_pos[i] = Shutter[i].tilt_real_pos; - Shutter[i].tiltmoving = 0; } ShutterLogPos(i); @@ -587,20 +594,19 @@ void ShutterAllowPreStartProcedure(uint8_t i) { #ifdef USE_RULES uint32_t uptime_Local=0; - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay Start. var%d <99>=<%s>, max10s?"),i+1, rules_vars[i]); - TasmotaGlobal.rules_flag.shutter_moving = 1; + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay Start? var%d <99>=<%s>, max10s?"),i+1, rules_vars[i]); XdrvRulesProcess(0); uptime_Local = TasmotaGlobal.uptime; while (uptime_Local+10 > TasmotaGlobal.uptime && (String)rules_vars[i] == "99") { loop(); } - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay Start. Done")); + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay Start. Done")); #endif // USE_RULES } void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) { - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: dir %d, delta1 %d, delta2 %d"),direction, (Shutter[i].open_max - Shutter[i].real_position) / Shutter[i].close_velocity, Shutter[i].real_position / Shutter[i].close_velocity); + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: dir %d, delta1 %d, delta2 %d"),direction, (Shutter[i].open_max - Shutter[i].real_position) / Shutter[i].close_velocity, Shutter[i].real_position / Shutter[i].close_velocity); if ( ( ( (1 == direction) && ((Shutter[i].open_max - Shutter[i].real_position) <= Shutter[i].min_realPositionChange)) || ( (-1 == direction) && (Shutter[i].real_position <= Shutter[i].min_realPositionChange)) ) && abs(Shutter[i].tilt_real_pos-Shutter[i].tilt_target_pos) <= Shutter[i].min_TiltChange) { @@ -616,26 +622,33 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) break; #endif } + Shutter[i].accelerator = ShutterGlobal.open_velocity_max / (Shutter[i].motordelay>0 ? Shutter[i].motordelay : 1); Shutter[i].target_position = target_pos; Shutter[i].start_position = Shutter[i].real_position; TasmotaGlobal.rules_flag.shutter_moving = 1; ShutterAllowPreStartProcedure(i); - Shutter[i].time = 0; - Shutter[i].direction = direction; + Shutter[i].time = Shutter[i].last_reported_time = 0; + + // avoid file system writes during move to minimize missing steps + savedata_original = Settings->save_data; + Settings->save_data = 0; // will be restored after movement + + TasmotaGlobal.save_data_counter = Settings->save_data; ShutterGlobal.skip_relay_change = 0; TasmotaGlobal.rules_flag.shutter_moved = 0; ShutterGlobal.start_reported = 0; Shutter[i].tilt_real_pos = tmax(tmin(Shutter[i].tilt_real_pos,Shutter[i].tilt_config[1]),Shutter[i].tilt_config[0]); Shutter[i].tilt_start_pos = Shutter[i].tilt_real_pos; if (Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0] != 0) { - Shutter[i].venetian_delay = (Shutter[i].direction > 0 ? Shutter[i].tilt_config[1]-Shutter[i].tilt_real_pos : Shutter[i].tilt_real_pos-Shutter[i].tilt_config[0]) * Shutter[i].tilt_config[2] / (Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0]); - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: real %d, start %d, counter %d,freq_max %d, dir %d, freq %d"),Shutter[i].real_position, Shutter[i].start_position ,RtcSettings.pulse_counter[i],ShutterGlobal.open_velocity_max , Shutter[i].direction ,ShutterGlobal.open_velocity_max ); - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: %d VenetianDelay: %d, Pos: %d, Dir: %d, Delta: %d, Durat: %d, Start: %d, Target: %d"), - // i, Shutter[i].venetian_delay, Shutter[i].tilt_real_pos,Shutter[i].direction,(Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0]), Shutter[i].tilt_config[2],Shutter[i].tilt_start_pos,Shutter[i].tilt_target_pos); + Shutter[i].venetian_delay = (direction > 0 ? Shutter[i].tilt_config[1]-Shutter[i].tilt_real_pos : Shutter[i].tilt_real_pos-Shutter[i].tilt_config[0]) * Shutter[i].tilt_config[2] / (Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0]); + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: real %d, start %d, counter %d,freq_max %d, dir %d, freq %d"),Shutter[i].real_position, Shutter[i].start_position ,RtcSettings.pulse_counter[i],ShutterGlobal.open_velocity_max , direction ,ShutterGlobal.open_velocity_max ); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: VenetianDelay: %d, Pos: %d, Dir: %d, Delta: %d, Dur: %d, StartP: %d, TgtP: %d"), + Shutter[i].venetian_delay, Shutter[i].tilt_real_pos,direction,(Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0]), Shutter[i].tilt_config[2],Shutter[i].tilt_start_pos,Shutter[i].tilt_target_pos); } } - AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Start shtr%d from %d to %d in direction %d"), i, Shutter[i].start_position, Shutter[i].target_position, Shutter[i].direction); + //AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Start shtr%d from %d to %d in dir: %d"), i, Shutter[i].start_position, Shutter[i].target_position, direction); + Shutter[i].direction = direction; // Last action. This causes RTC to start. } int32_t ShutterCalculatePosition(uint32_t i) @@ -685,8 +698,8 @@ void ShutterRelayChanged(void) // SRC_IGNORE added because INTERLOCK function bite causes this as last source for changing the relay. //uint8 manual_relays_changed = ((ShutterGlobal.RelayCurrentMask >> (Settings->shutter_startrelay[i] -1)) & 3) && SRC_IGNORE != TasmotaGlobal.last_source && SRC_SHUTTER != TasmotaGlobal.last_source && SRC_PULSETIMER != TasmotaGlobal.last_source ; uint8 manual_relays_changed = ((ShutterGlobal.RelayCurrentMask >> (Settings->shutter_startrelay[i] -1)) & 3) && SRC_SHUTTER != TasmotaGlobal.last_source && SRC_PULSETIMER != TasmotaGlobal.last_source ; - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Source %s, Powerstate %ld, RelayMask %d, ManualChange %d"), - i+1, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed); + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Source %s, Powerstate %ld, RelayMask %d, ManualChange %d"), + // i+1, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed); if (manual_relays_changed) { //ShutterGlobal.skip_relay_change = true; ShutterLimitRealAndTargetPositions(i); @@ -955,7 +968,7 @@ void ShutterSetPosition(uint32_t device, uint32_t position) void ShutterToggle(bool dir) { - AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Payload toggle: %d, i %d, dir %d, lastdir %d"), XdrvMailbox.payload, XdrvMailbox.index, dir, Shutter[XdrvMailbox.index-1].lastdirection); + AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Toggle: %d, i %d, dir %d, lastdir %d"), XdrvMailbox.payload, XdrvMailbox.index, dir, Shutter[XdrvMailbox.index-1].lastdirection); if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { XdrvMailbox.index = XdrvMailbox.payload; } @@ -1149,8 +1162,10 @@ void CmndShutterPosition(void) int8_t new_shutterdirection; if (abs(Shutter[index].target_position - Shutter[index].real_position ) > Shutter[index].min_realPositionChange) { new_shutterdirection = Shutter[index].real_position < Shutter[index].target_position ? 1 : -1; + Shutter[index].tiltmoving = 0; } else { new_shutterdirection = Shutter[index].tilt_real_pos < Shutter[index].tilt_target_pos ? 1 : -1; + Shutter[index].tiltmoving = 1; } if (Shutter[index].direction == -new_shutterdirection) { @@ -1444,30 +1459,6 @@ void CmndShutterSetHalfway(void) } } -void CmndShutterSetTilt(void) -{ - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) { - if (XdrvMailbox.payload != -99 ) { - Shutter[XdrvMailbox.index -1].tilt_target_pos = tmin(tmax(XdrvMailbox.payload, Shutter[XdrvMailbox.index -1].tilt_config[0]), Shutter[XdrvMailbox.index -1].tilt_config[1]); - XdrvMailbox.payload = -99; - } - if ((XdrvMailbox.data_len > 1) && (XdrvMailbox.payload <= 0)) { - if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) ) { - Shutter[XdrvMailbox.index -1].tilt_target_pos = Shutter[XdrvMailbox.index -1].tilt_config[3]; // open position - XdrvMailbox.payload = -99; - } - if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) ) { - Shutter[XdrvMailbox.index -1].tilt_target_pos = Shutter[XdrvMailbox.index -1].tilt_config[4]; // close position - XdrvMailbox.payload = -99; - } - } - } - XdrvMailbox.data[0] = '\0'; - ResponseCmndNumber(Shutter[XdrvMailbox.index -1].tilt_target_pos); - Shutter[XdrvMailbox.index -1].tiltmoving = 1; - CmndShutterPosition(); -} - void CmndShutterFrequency(void) { if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 20000)) { @@ -1566,7 +1557,8 @@ void CmndShutterCalibration(void) } } -void ShutterOptionsSetHelper(uint16_t option){ +void ShutterOptionsSetHelper(uint16_t option) +{ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) { if (XdrvMailbox.payload == 0) { Settings->shutter_options[XdrvMailbox.index -1] &= ~(option); @@ -1577,23 +1569,52 @@ void ShutterOptionsSetHelper(uint16_t option){ } } -void CmndShutterInvert(void) { +void CmndShutterInvert(void) +{ ShutterOptionsSetHelper(1); } -void CmndShutterLock(void) { +void CmndShutterLock(void) +{ ShutterOptionsSetHelper(2); } -void CmndShutterEnableEndStopTime(void) { +void CmndShutterEnableEndStopTime(void) +{ ShutterOptionsSetHelper(4); } -void CmndShutterInvertWebButtons(void) { +void CmndShutterInvertWebButtons(void) +{ ShutterOptionsSetHelper(8); } -void CmndShutterTiltConfig(void) { +void CmndShutterSetTilt(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) { + if (XdrvMailbox.payload != -99 ) { + Shutter[XdrvMailbox.index -1].tilt_target_pos = tmin(tmax(XdrvMailbox.payload, Shutter[XdrvMailbox.index -1].tilt_config[0]), Shutter[XdrvMailbox.index -1].tilt_config[1]); + XdrvMailbox.payload = -99; + } + if ((XdrvMailbox.data_len > 1) && (XdrvMailbox.payload <= 0)) { + if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) ) { + Shutter[XdrvMailbox.index -1].tilt_target_pos = Shutter[XdrvMailbox.index -1].tilt_config[3]; // open position + XdrvMailbox.payload = -99; + } + if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) ) { + Shutter[XdrvMailbox.index -1].tilt_target_pos = Shutter[XdrvMailbox.index -1].tilt_config[4]; // close position + XdrvMailbox.payload = -99; + } + } + } + XdrvMailbox.data[0] = '\0'; + ResponseCmndNumber(Shutter[XdrvMailbox.index -1].tilt_target_pos); + Shutter[XdrvMailbox.index -1].tiltmoving = 1; + CmndShutterPosition(); +} + +void CmndShutterTiltConfig(void) +{ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) { if (XdrvMailbox.data_len > 0) { uint8_t i = 0; @@ -1615,6 +1636,18 @@ void CmndShutterTiltConfig(void) { } } +void CmndShutterTiltIncDec(void) +{ + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Change in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, TasmotaGlobal.last_source ); + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) { + if (XdrvMailbox.data_len > 0) { + XdrvMailbox.payload = Shutter[XdrvMailbox.index -1].tilt_target_pos+XdrvMailbox.payload; + CmndShutterSetTilt(); + } + } + ResponseCmndNumber(Shutter[XdrvMailbox.index -1].tilt_target_pos); +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/