mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Merge branch 'development' into pre-release-12.3
This commit is contained in:
commit
23cbdb93b0
@ -15,13 +15,15 @@ All notable changes to this project will be documented in this file.
|
||||
### Changed
|
||||
- TasmotaSerial library from v3.5.0 to v3.6.0
|
||||
- Removed leading spaces on commands ``(S)SerialSend1 to 6`` but keep on duplicate commands ``(S)SerialSend11 to 16`` (#16723)
|
||||
- MQTT now uses Tasmota's DNS resolver instead of LWIP (#17387)
|
||||
- Shutter bug fixes and functionality upgrade (#17380)
|
||||
|
||||
### Fixed
|
||||
- TasmotaSerial ``read(buffer, size)`` regression from v9.3.0
|
||||
- RCSwitch exception 0/6 on some protocols (#17285)
|
||||
- ESP32 exception 28 when RtcNtpServer is enabled on restart (#17338)
|
||||
- Analog MQ exception 28 on restart (#17271)
|
||||
- ESP32 fix ``Ping``
|
||||
- ESP32 fix ``Ping`` (#17373)
|
||||
|
||||
## [12.2.0.5] 20221129
|
||||
### Added
|
||||
|
@ -155,6 +155,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||
- AC PWM dimmer lineair power distribution [#17177](https://github.com/arendst/Tasmota/issues/17177)
|
||||
- Zigbee improved Aqara plug support and completed cluster 0x0702 [#17073](https://github.com/arendst/Tasmota/issues/17073)
|
||||
- Removed leading spaces on commands ``(S)SerialSend1 to 6`` but keep on duplicate commands ``(S)SerialSend11 to 16`` [#16723](https://github.com/arendst/Tasmota/issues/16723
|
||||
- Shutter bug fixes and functionality upgrade [#17380](https://github.com/arendst/Tasmota/issues/17380
|
||||
- MQTT now uses Tasmota's DNS resolver instead of LWIP [#17387](https://github.com/arendst/Tasmota/issues/17387
|
||||
|
||||
### Fixed
|
||||
- TasmotaSerial ``read(buffer, size)`` regression from v9.3.0
|
||||
|
@ -299,7 +299,7 @@ int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port, int32_t timeout
|
||||
setLastError(ERR_TCP_CONNECT);
|
||||
return 0;
|
||||
}
|
||||
return _connectSSL(nullptr);
|
||||
return _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str());
|
||||
}
|
||||
#else // ESP32
|
||||
int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) {
|
||||
|
@ -126,6 +126,10 @@ class WiFiClientSecure_light : public WiFiClient {
|
||||
|
||||
void setInsecure();
|
||||
|
||||
void setDomainName(const char * domain) {
|
||||
_domain = domain;
|
||||
}
|
||||
|
||||
private:
|
||||
void _clear();
|
||||
bool _ctx_present;
|
||||
@ -172,6 +176,9 @@ class WiFiClientSecure_light : public WiFiClient {
|
||||
// record the maximum use of ThunkStack for monitoring
|
||||
size_t _max_thunkstack_use;
|
||||
|
||||
// domain name (string) that will be used with SNI when the address provided is already resolved
|
||||
String _domain;
|
||||
|
||||
// ALPN
|
||||
const char ** _alpn_names;
|
||||
size_t _alpn_num;
|
||||
|
@ -29,8 +29,7 @@ def map_gzip(source, target, env):
|
||||
if not tasmotapiolib.is_env_set(tasmotapiolib.DISABLE_MAP_GZ, env):
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [map_gzip])
|
||||
|
||||
# gzip only for ESP8266
|
||||
if env["PIOPLATFORM"] != "espressif32":
|
||||
if tasmotapiolib.is_env_set(tasmotapiolib.ENABLE_ESP32_GZ, env) or env["PIOPLATFORM"] != "espressif32":
|
||||
from zopfli.gzip import compress
|
||||
def bin_gzip(source, target, env):
|
||||
# create string with location and file names based on variant
|
||||
@ -50,7 +49,7 @@ if env["PIOPLATFORM"] != "espressif32":
|
||||
ORG_FIRMWARE_SIZE = bin_file.stat().st_size
|
||||
GZ_FIRMWARE_SIZE = gzip_file.stat().st_size
|
||||
|
||||
if ORG_FIRMWARE_SIZE > 995326:
|
||||
if ORG_FIRMWARE_SIZE > 995326 and env["PIOPLATFORM"] != "espressif32":
|
||||
print(
|
||||
"\u001b[31;1m!!! Tasmota firmware size is too big with {} bytes. Max size is 995326 bytes !!! \u001b[0m".format(
|
||||
ORG_FIRMWARE_SIZE
|
||||
|
@ -25,8 +25,10 @@ import pathlib
|
||||
import os
|
||||
|
||||
# === AVAILABLE OVERRIDES ===
|
||||
# if set to 1, will not gzip esp8266 bin files
|
||||
# if set to 1, will not gzip bin files at all
|
||||
DISABLE_BIN_GZ = "disable_bin_gz"
|
||||
# if set to 1, will gzip esp32 bin files
|
||||
ENABLE_ESP32_GZ = "enable_esp32_gz"
|
||||
# if set, an alternative ptah to put generated .bin files, relative to project directory
|
||||
BIN_DIR = "bin_dir"
|
||||
# if set to 1, will not gzip generated .map files
|
||||
|
@ -58,8 +58,10 @@ lib_extra_dirs =
|
||||
;disable_map_gz = 1
|
||||
; Uncomment and specify a folder where to place the map file(s) (default set to folder build_output)
|
||||
;map_dir = /tmp/map_files/
|
||||
; Uncomment if you do NOT want additionally gzipped firmware file(s)
|
||||
; Uncomment if you do NOT want additionally gzipped firmware file(s) at all
|
||||
;disable_bin_gz = 1
|
||||
; Uncomment if you want additionally gzipped esp32x firmware file(s)
|
||||
;enable_esp32_gz = 1
|
||||
; Uncomment and specify a folder where to place the firmware file(s) (default set to folder build_output)
|
||||
;bin_dir = /tmp/bin_files/
|
||||
|
||||
|
@ -738,6 +738,7 @@
|
||||
#define D_CMND_SHUTTER_TILTCONFIG "TiltConfig"
|
||||
#define D_CMND_SHUTTER_SETTILT "Tilt"
|
||||
#define D_CMND_SHUTTER_TILTINCDEC "TiltChange"
|
||||
#define D_CMND_SHUTTER_MOTORSTOP "MotorStop"
|
||||
|
||||
// Commands xdrv_32_hotplug.ino
|
||||
#define D_CMND_HOTPLUG "HotPlug"
|
||||
|
@ -264,6 +264,8 @@
|
||||
#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
|
||||
#endif // enable USE_MI_HOMEKIT
|
||||
|
||||
#define USE_ETHERNET // Add support for ethernet (+20k code
|
||||
|
||||
#endif // FIRMWARE_BLUETOOTH
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -454,6 +456,8 @@
|
||||
|
||||
#define USE_IR_REMOTE
|
||||
|
||||
#define USE_ETHERNET // Add support for ethernet (+20k code
|
||||
|
||||
#endif // FIRMWARE_TASMOTA_LVGL *******************************************************************
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -730,8 +730,8 @@ typedef struct {
|
||||
#endif // ESP32
|
||||
uint16_t artnet_universe; // 734
|
||||
uint16_t modbus_sbaudrate; // 736
|
||||
|
||||
uint8_t free_esp32_738[5]; // 738
|
||||
uint16_t shutter_motorstop; // 738
|
||||
uint8_t free_esp32_73A[3]; // 73A
|
||||
|
||||
uint8_t novasds_startingoffset; // 73D
|
||||
uint8_t web_color[18][3]; // 73E
|
||||
|
@ -1065,11 +1065,12 @@ void MqttReconnect(void) {
|
||||
MqttClient.setCallback(MqttDataHandler);
|
||||
|
||||
// Keep using hostname to solve rc -4 issues
|
||||
if (!WifiDnsPresent(SettingsText(SET_MQTT_HOST))) {
|
||||
IPAddress ip;
|
||||
if (!WifiHostByName(SettingsText(SET_MQTT_HOST), ip)) {
|
||||
MqttDisconnected(-5); // MQTT_DNS_DISCONNECTED
|
||||
return;
|
||||
}
|
||||
MqttClient.setServer(SettingsText(SET_MQTT_HOST), Settings->mqtt_port);
|
||||
MqttClient.setServer(ip, Settings->mqtt_port);
|
||||
|
||||
if (2 == Mqtt.initial_connection_state) { // Executed once just after power on and wifi is connected
|
||||
Mqtt.initial_connection_state = 1;
|
||||
@ -1085,9 +1086,11 @@ void MqttReconnect(void) {
|
||||
}
|
||||
|
||||
#ifdef USE_MQTT_TLS
|
||||
|
||||
uint32_t mqtt_connect_time = millis();
|
||||
if (Mqtt.mqtt_tls) {
|
||||
tlsClient->stop();
|
||||
tlsClient->setDomainName(SettingsText(SET_MQTT_HOST)); // set domain name for TLS SNI (selection of certificate based on domain name)
|
||||
} else {
|
||||
MqttClient.setClient(EspClient);
|
||||
}
|
||||
|
@ -56,8 +56,8 @@ int32_t next_possible_stop_position = 0;
|
||||
int32_t current_real_position = 0;
|
||||
int32_t current_pwm_velocity = 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,};
|
||||
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,};
|
||||
enum ShutterButtonStates { SHT_NOT_PRESSED, SHT_PRESSED_MULTI, SHT_PRESSED_HOLD, SHT_PRESSED_IMMEDIATE, SHT_PRESSED_EXT_HOLD, SHT_PRESSED_MULTI_SIMULTANEOUS, SHT_PRESSED_HOLD_SIMULTANEOUS, SHT_PRESSED_EXT_HOLD_SIMULTANEOUS,};
|
||||
|
||||
@ -67,7 +67,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_TILTINCDEC;
|
||||
D_CMND_SHUTTER_UNITTEST "|" D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC "|" D_CMND_SHUTTER_MOTORSTOP;
|
||||
|
||||
void (* const ShutterCommand[])(void) PROGMEM = {
|
||||
&CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterToggleDir, &CmndShutterStop, &CmndShutterPosition,
|
||||
@ -75,7 +75,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,&CmndShutterTiltIncDec};
|
||||
&CmndShutterUnitTest,&CmndShutterTiltConfig,&CmndShutterSetTilt,&CmndShutterTiltIncDec,&CmndShutterMotorStop};
|
||||
|
||||
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}";
|
||||
@ -111,6 +111,7 @@ struct SHUTTER {
|
||||
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;
|
||||
uint32_t last_stop_time = 0; // record the last time the relay was switched off
|
||||
} Shutter[MAX_SHUTTERS];
|
||||
|
||||
struct SHUTTERGLOBAL {
|
||||
@ -276,8 +277,9 @@ void ShutterInit(void)
|
||||
}
|
||||
for (uint32_t i = 0; i < MAX_SHUTTERS; i++) {
|
||||
// set startrelay to 1 on first init, but only to shutter 1. 90% usecase
|
||||
Settings->shutter_startrelay[i] = (Settings->shutter_startrelay[i] == 0 && i == 0? 1 : Settings->shutter_startrelay[i]);
|
||||
if (Settings->shutter_startrelay[i] && (Settings->shutter_startrelay[i] <= MAX_RELAYS )) {
|
||||
//Settings->shutter_startrelay[i] = (Settings->shutter_startrelay[i] == 0 && i == 0? 1 : Settings->shutter_startrelay[i]);
|
||||
if (Settings->shutter_startrelay[i] && (Settings->shutter_startrelay[i] <= 32 )) {
|
||||
bool relay_in_interlock = false;
|
||||
TasmotaGlobal.shutters_present++;
|
||||
|
||||
// Add the two relays to the mask to knaw they belong to shutters
|
||||
@ -293,31 +295,32 @@ void ShutterInit(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (Settings->shutter_mode == SHT_UNDEF) {
|
||||
bool relay_in_interlock = false;
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Mode undef.. calculate..."));
|
||||
|
||||
for (uint32_t j = 0; j < MAX_INTERLOCKS * Settings->flag.interlock; j++) { // CMND_INTERLOCK - Enable/disable interlock
|
||||
//AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Interlock state i=%d %d, flag %d, Shuttermask %d, MaskedIL %d"),i, Settings->interlock[i], Settings->flag.interlock,ShutterGlobal.RelayShutterMask, Settings->interlock[i]&ShutterGlobal.RelayShutterMask);
|
||||
if (Settings->interlock[j] && (Settings->interlock[j] & ShutterGlobal.RelayShutterMask)) {
|
||||
//AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Relay in Interlock group"));
|
||||
relay_in_interlock = true;
|
||||
}
|
||||
// Check if the relay is in an INTERLOCK group. required to set the right mode or
|
||||
// verify that on SHT_TIME INTERLOCK is set
|
||||
for (uint32_t j = 0; j < MAX_INTERLOCKS * Settings->flag.interlock; j++) { // CMND_INTERLOCK - Enable/disable interlock
|
||||
//AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Interlock state i=%d %d, flag %d, Shuttermask %d, MaskedIL %d"),i, Settings->interlock[i], Settings->flag.interlock,ShutterGlobal.RelayShutterMask, Settings->interlock[i]&ShutterGlobal.RelayShutterMask);
|
||||
if (Settings->interlock[j] && (Settings->interlock[j] & ShutterGlobal.RelayShutterMask)) {
|
||||
//AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Relay in Interlock group"));
|
||||
relay_in_interlock = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (relay_in_interlock) {
|
||||
ShutterGlobal.position_mode = SHT_TIME;
|
||||
} else {
|
||||
ShutterGlobal.position_mode = SHT_TIME_UP_DOWN;
|
||||
if (Settings->shutter_mode == SHT_AUTOCONFIG || Settings->shutter_mode == SHT_UNDEF) {
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Mode undef.. calculate..."));
|
||||
ShutterGlobal.position_mode = SHT_TIME;
|
||||
if (!relay_in_interlock) {
|
||||
// temporary to maintain old functionality
|
||||
if (Settings->shutter_mode == SHT_UNDEF) {
|
||||
ShutterGlobal.position_mode = SHT_TIME_UP_DOWN;
|
||||
}
|
||||
if (PinUsed(GPIO_PWM1, i) && PinUsed(GPIO_CNTR1, i)) {
|
||||
ShutterGlobal.position_mode = SHT_COUNTER;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ShutterGlobal.position_mode = Settings->shutter_mode;
|
||||
}
|
||||
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("SHT: ShutterMode: %d"), ShutterGlobal.position_mode);
|
||||
// main function for stepper and servos to control velocity and acceleration.
|
||||
TickerShutter.attach_ms(50, ShutterRtc50mS );
|
||||
|
||||
@ -369,6 +372,14 @@ void ShutterInit(void)
|
||||
Shutter[i].min_realPositionChange = 0;
|
||||
Shutter[i].min_TiltChange = 0;
|
||||
break;
|
||||
case SHT_TIME:
|
||||
// Test is the relays are in interlock mode. Disable shuttermode if error
|
||||
if (!relay_in_interlock) {
|
||||
TasmotaGlobal.shutters_present = 0,
|
||||
AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ERROR: Shtr%d Relays are not in INTERLOCK. Pls read documentation. Shutter DISABLE. Fix and REBOOT"),i+1);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
@ -382,6 +393,9 @@ void ShutterInit(void)
|
||||
}
|
||||
ShutterLimitRealAndTargetPositions(i);
|
||||
Settings->shutter_accuracy = 1;
|
||||
Settings->shutter_mode = ShutterGlobal.position_mode;
|
||||
// initialize MotorStop time with 500ms if not set
|
||||
Settings->shutter_motorstop = Settings->shutter_motorstop == 0?500:Settings->shutter_motorstop;
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,7 +582,22 @@ void ShutterPowerOff(uint8_t i)
|
||||
if (Settings->save_data) {
|
||||
TasmotaGlobal.save_data_counter = Settings->save_data;
|
||||
}
|
||||
delay(MOTOR_STOP_TIME);
|
||||
//delay(MOTOR_STOP_TIME);
|
||||
Shutter[i].last_stop_time = millis();
|
||||
}
|
||||
|
||||
void ShutterWaitForMotorStop(uint8_t index)
|
||||
{
|
||||
Shutter[index-1].last_stop_time = millis();
|
||||
ShutterWaitForMotorStart(index);
|
||||
}
|
||||
|
||||
void ShutterWaitForMotorStart(uint8_t index)
|
||||
{
|
||||
while (millis() < Shutter[index-1].last_stop_time + Settings->shutter_motorstop) {
|
||||
loop();
|
||||
}
|
||||
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Stoptime done"));
|
||||
}
|
||||
|
||||
void ShutterUpdatePosition(void)
|
||||
@ -583,8 +612,8 @@ void ShutterUpdatePosition(void)
|
||||
}
|
||||
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,
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d 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"),
|
||||
i+1, 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) ||
|
||||
@ -661,6 +690,7 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos)
|
||||
ShutterGlobal.skip_relay_change = 1;
|
||||
} else {
|
||||
Shutter[i].pwm_velocity = 0;
|
||||
ShutterWaitForMotorStart(i+1);
|
||||
switch (ShutterGlobal.position_mode) {
|
||||
#ifdef SHUTTER_STEPPER
|
||||
case SHT_COUNTER:
|
||||
@ -704,6 +734,7 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos)
|
||||
}
|
||||
}
|
||||
//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.
|
||||
}
|
||||
|
||||
@ -1189,6 +1220,8 @@ void CmndShutterPosition(void)
|
||||
// special handling fo UP,DOWN,TOGGLE,STOP command comming with payload -99
|
||||
// STOP will come with payload 0 because predefined value in TASMOTA
|
||||
if ((XdrvMailbox.data_len > 3) && (XdrvMailbox.payload <= 0)) {
|
||||
// set len to 0 to avoid loop on close where payload is 0
|
||||
XdrvMailbox.data_len = 0;
|
||||
if ( ((Shutter[index].direction==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPOPEN))) {
|
||||
CmndShutterOpen();
|
||||
return;
|
||||
@ -1279,9 +1312,11 @@ void CmndShutterPosition(void)
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("SHT: Garage not move in this direction: %d"), Shutter[index].switch_mode == SHT_PULSE);
|
||||
for (uint8_t k=0 ; k <= (uint8_t)(Shutter[index].switch_mode == SHT_PULSE) ; k++) {
|
||||
ExecuteCommandPowerShutter(Settings->shutter_startrelay[index], 1, SRC_SHUTTER);
|
||||
delay(MOTOR_STOP_TIME);
|
||||
//delay(MOTOR_STOP_TIME);
|
||||
ShutterWaitForMotorStop(index);
|
||||
ExecuteCommandPowerShutter(Settings->shutter_startrelay[index], 0, SRC_SHUTTER);
|
||||
delay(MOTOR_STOP_TIME);
|
||||
//delay(MOTOR_STOP_TIME);
|
||||
ShutterWaitForMotorStop(index);
|
||||
}
|
||||
// reset shutter time to avoid 2 seconds above count as runtime
|
||||
Shutter[index].time = 0;
|
||||
@ -1363,10 +1398,9 @@ void CmndShutterMotorDelay(void)
|
||||
|
||||
void CmndShutterMode(void)
|
||||
{
|
||||
if (!XdrvMailbox.usridx && !XdrvMailbox.data_len) {
|
||||
if (!XdrvMailbox.usridx) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= MAX_MODES)) {
|
||||
ShutterGlobal.position_mode = XdrvMailbox.payload;
|
||||
Settings->shutter_mode = XdrvMailbox.payload;
|
||||
Settings->shutter_mode = ShutterGlobal.position_mode = XdrvMailbox.payload;
|
||||
ShutterInit();
|
||||
}
|
||||
ResponseCmndNumber(ShutterGlobal.position_mode);
|
||||
@ -1375,14 +1409,22 @@ void CmndShutterMode(void)
|
||||
|
||||
void CmndShutterRelay(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 64) && (XdrvMailbox.index <= MAX_SHUTTERS)) {
|
||||
Settings->shutter_startrelay[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 32) && (XdrvMailbox.index <= MAX_SHUTTERS)) {
|
||||
//Settings->shutter_startrelay[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
if (XdrvMailbox.payload > 0) {
|
||||
ShutterGlobal.RelayShutterMask |= 3 << (XdrvMailbox.payload - 1);
|
||||
} else {
|
||||
ShutterGlobal.RelayShutterMask ^= 3 << (Settings->shutter_startrelay[XdrvMailbox.index -1] - 1);
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: relold:%d index:%d, mode:%d, relaymask: %ld"),
|
||||
Settings->shutter_startrelay[XdrvMailbox.index -1] , XdrvMailbox.index ,Settings->shutter_mode, ShutterGlobal.RelayShutterMask );
|
||||
if (Settings->shutter_startrelay[XdrvMailbox.index -1] == 0 && XdrvMailbox.index == 1 && Settings->shutter_mode == SHT_UNDEF) {
|
||||
// first shutter was not defined, maybe init
|
||||
Settings->shutter_mode = SHT_AUTOCONFIG;
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Autoconfig"));
|
||||
}
|
||||
Settings->shutter_startrelay[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
|
||||
ShutterInit();
|
||||
// if payload is 0 to disable the relay there must be a reboot. Otherwhise does not work
|
||||
}
|
||||
@ -1391,7 +1433,7 @@ void CmndShutterRelay(void)
|
||||
// {"ShutterRelay1":"1","ShutterRelay2":"3","ShutterRelay3":"5"}
|
||||
Response_P(PSTR("{"));
|
||||
for (uint32_t i = start; i < end; i++) {
|
||||
ResponseAppend_P(PSTR("%s\"" D_PRFX_SHUTTER D_CMND_SHUTTER_RELAY "%d\":\"%d\""), (i)?",":"", i+1,Settings->shutter_startrelay[i]);
|
||||
ResponseAppend_P(PSTR("%s\"" D_PRFX_SHUTTER D_CMND_SHUTTER_RELAY "%d\":\"%d\""), (i>start)?",":"", i+1,Settings->shutter_startrelay[i]);
|
||||
}
|
||||
ResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
@ -1729,6 +1771,16 @@ void CmndShutterTiltIncDec(void)
|
||||
}
|
||||
}
|
||||
|
||||
void CmndShutterMotorStop(void)
|
||||
{
|
||||
if (!XdrvMailbox.usridx) {
|
||||
if ((XdrvMailbox.payload >= 0) ) {
|
||||
Settings->shutter_motorstop = XdrvMailbox.payload;
|
||||
}
|
||||
ResponseCmndNumber(Settings->shutter_motorstop);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
@ -1738,6 +1790,10 @@ bool Xdrv27(uint32_t function)
|
||||
bool result = false;
|
||||
|
||||
if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support
|
||||
uint8_t counter = XdrvMailbox.index==0?1:XdrvMailbox.index;
|
||||
uint8_t counterend = XdrvMailbox.index==0?TasmotaGlobal.shutters_present:XdrvMailbox.index;
|
||||
int32_t rescue_payload = XdrvMailbox.payload;
|
||||
uint32_t rescue_data_len = XdrvMailbox.data_len;
|
||||
switch (function) {
|
||||
case FUNC_PRE_INIT:
|
||||
ShutterInit();
|
||||
@ -1749,9 +1805,13 @@ bool Xdrv27(uint32_t function)
|
||||
//case FUNC_EVERY_250_MSECOND:
|
||||
ShutterReportPosition(false, MAX_SHUTTERS);
|
||||
break;
|
||||
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kShutterCommands, ShutterCommand);
|
||||
for (uint8_t i = counter; i <= counterend; i++) {
|
||||
XdrvMailbox.index = i;
|
||||
XdrvMailbox.payload = rescue_payload;
|
||||
XdrvMailbox.data_len = rescue_data_len;
|
||||
result = DecodeCommand(kShutterCommands, ShutterCommand);
|
||||
}
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
|
||||
|
@ -45,7 +45,7 @@ extern "C" {
|
||||
const uint32_t Ping_coarse = 1000; // interval between sending packets, 1 packet every second
|
||||
|
||||
typedef struct Ping_t {
|
||||
uint32 ip; // target IPv4 address
|
||||
ip_addr_t ip; // target IPv4 address
|
||||
Ping_t *next; // next object in linked list
|
||||
uint16_t seq_num; // next sequence number
|
||||
uint16_t seqno; // reject a packet already received
|
||||
@ -71,10 +71,11 @@ extern "C" {
|
||||
//
|
||||
// find the ping structure corresponding to the specified IP, or nullptr if not found
|
||||
//
|
||||
Ping_t ICACHE_FLASH_ATTR * t_ping_find(uint32_t ip) {
|
||||
Ping_t ICACHE_FLASH_ATTR * t_ping_find(const ip_addr_t *ip) {
|
||||
Ping_t *ping = ping_head;
|
||||
while (ping != nullptr) {
|
||||
if (ping->ip == ip) {
|
||||
if (ip_addr_cmp(&ping->ip, ip)) {
|
||||
// if (ping->ip == ip) {
|
||||
return ping;
|
||||
}
|
||||
ping = ping->next;
|
||||
@ -129,13 +130,11 @@ extern "C" {
|
||||
p = pbuf_alloc(PBUF_IP, ping_size, PBUF_RAM);
|
||||
if (!p) { return; }
|
||||
if ((p->len == p->tot_len) && (p->next == nullptr)) {
|
||||
ip_addr_t ping_target;
|
||||
struct icmp_echo_hdr *iecho;
|
||||
ip_addr_set_ip4_u32(&ping_target, ping->ip);
|
||||
iecho = (struct icmp_echo_hdr *) p->payload;
|
||||
|
||||
iecho = (struct icmp_echo_hdr *) p->payload;
|
||||
t_ping_prepare_echo(iecho, ping_size, ping);
|
||||
raw_sendto(raw, p, &ping_target);
|
||||
raw_sendto(raw, p, &ping->ip);
|
||||
}
|
||||
pbuf_free(p);
|
||||
}
|
||||
@ -166,7 +165,7 @@ extern "C" {
|
||||
// Reveived packet
|
||||
//
|
||||
static uint8_t ICACHE_FLASH_ATTR t_ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) {
|
||||
Ping_t *ping = t_ping_find(ip_addr_get_ip4_u32(addr));
|
||||
Ping_t *ping = t_ping_find(addr);
|
||||
|
||||
if (nullptr == ping) { // unknown source address
|
||||
return 0; // don't eat the packet and ignore it
|
||||
@ -234,14 +233,18 @@ extern "C" {
|
||||
// -2: unable to resolve address
|
||||
int32_t t_ping_start(const char *hostname, uint32_t count) {
|
||||
IPAddress ipfull;
|
||||
if (!WifiHostByName(hostname, ipfull)) {
|
||||
ipfull = 0xFFFFFFFF;
|
||||
}
|
||||
bool host_resolved = WifiHostByName(hostname, ipfull);
|
||||
|
||||
uint32_t ip = ipfull;
|
||||
ip_addr_t ip;
|
||||
ip_addr_set_any_val(false, ip);
|
||||
#ifdef USE_IPV6
|
||||
ip = (ip_addr_t)ipfull;
|
||||
#else
|
||||
ip_addr_set_ip4_u32_val(ip, (uint32_t)ipfull);
|
||||
#endif
|
||||
|
||||
// check if pings are already ongoing for this IP
|
||||
if (0xFFFFFFFF != ip && t_ping_find(ip)) {
|
||||
if (host_resolved && t_ping_find(&ip)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -259,7 +262,7 @@ extern "C" {
|
||||
ping->next = ping_head;
|
||||
ping_head = ping; // insert at head
|
||||
|
||||
if (0xFFFFFFFF == ip) { // If invalid address, set as completed
|
||||
if (!host_resolved) { // If invalid address, set as completed
|
||||
ping->done = true;
|
||||
return -2;
|
||||
}
|
||||
@ -285,9 +288,9 @@ void PingResponsePoll(void) {
|
||||
while (ping != nullptr) {
|
||||
if (ping->done) {
|
||||
uint32_t success = ping->success_count;
|
||||
uint32_t ip = ping->ip;
|
||||
bool resolved = !ip_addr_isany_val(ping->ip);
|
||||
|
||||
if (0xFFFFFFFF == ip) {
|
||||
if (!resolved) {
|
||||
Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{"
|
||||
"\"Reachable\":false"
|
||||
",\"IP\":\"\""
|
||||
@ -298,7 +301,7 @@ void PingResponsePoll(void) {
|
||||
} else {
|
||||
Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{"
|
||||
"\"Reachable\":%s"
|
||||
",\"IP\":\"%d.%d.%d.%d\""
|
||||
",\"IP\":\"%s\""
|
||||
",\"Success\":%d"
|
||||
",\"Timeout\":%d"
|
||||
",\"MinTime\":%d"
|
||||
@ -307,7 +310,12 @@ void PingResponsePoll(void) {
|
||||
"}}}"),
|
||||
ping->hostname.c_str(),
|
||||
success ? PSTR("true") : PSTR("false"),
|
||||
ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24,
|
||||
#ifdef USE_IPV6
|
||||
IPAddress(ping->ip).toString().c_str(),
|
||||
#else
|
||||
IPAddress(ip_addr_get_ip4_u32(&ping->ip)).toString().c_str(),
|
||||
#endif
|
||||
// ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24,
|
||||
success,
|
||||
ping->timeout_count,
|
||||
success ? ping->min_time : 0,
|
||||
|
@ -194,7 +194,11 @@ extern "C" {
|
||||
timeout = be_toint(vm, 4);
|
||||
}
|
||||
// open connection
|
||||
bool success = tcp->connect(address, port, timeout);
|
||||
IPAddress ipaddr;
|
||||
bool success = WifiHostByName(address, ipaddr);
|
||||
if (success) {
|
||||
success = tcp->connect(ipaddr, port, timeout);
|
||||
}
|
||||
be_pushbool(vm, success);
|
||||
be_return(vm); /* return self */
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user