mirror of https://github.com/arendst/Tasmota.git
Bump version v13.4.0.4
- Add command ``PowerLock`` to disable power control of selected outputs (#21081)
This commit is contained in:
parent
fbe83585bd
commit
fe89774fe0
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -3,7 +3,19 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
## [Unreleased] - Development
|
||||
|
||||
## [13.4.0.3]
|
||||
## [13.4.0.4]
|
||||
### Added
|
||||
- Command ``PowerLock`` to disable power control of selected outputs (#21081)
|
||||
|
||||
### Breaking Changed
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
|
||||
### Removed
|
||||
|
||||
## [13.4.0.3] 20240402
|
||||
### Added
|
||||
- Zigbee support for attributes of type `uint48` used by energy monitoring (#20992)
|
||||
- Support for single channel EU863-870 LoRaWanBridge (#17790)
|
||||
|
|
|
@ -116,8 +116,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||
|
||||
[Complete list](BUILDS.md) of available feature and sensors.
|
||||
|
||||
## Changelog v13.4.0.3
|
||||
## Changelog v13.4.0.4
|
||||
### Added
|
||||
- Command ``PowerLock`` to disable power control of selected outputs [#21081](https://github.com/arendst/Tasmota/issues/21081)
|
||||
- Support for calculated heat index if temperature and humidity is available with ``#define USE_HEAT_INDEX`` [#4771](https://github.com/arendst/Tasmota/issues/4771)
|
||||
- Support for LoRa and single channel EU863-870 LoRaWanBridge [#17790](https://github.com/arendst/Tasmota/issues/17790)
|
||||
- Support for AMS5915/AMS6915 temperature and pressure sensors [#20814](https://github.com/arendst/Tasmota/issues/20814)
|
||||
|
|
|
@ -286,6 +286,7 @@
|
|||
#define D_CMND_STATE "State"
|
||||
#define D_CMND_POWER "Power"
|
||||
#define D_CMND_TIMEDPOWER "TimedPower"
|
||||
#define D_CMND_POWERLOCK "PowerLock"
|
||||
#define D_CMND_FANSPEED "FanSpeed"
|
||||
#define D_CMND_POWERONSTATE "PowerOnState"
|
||||
#define D_CMND_PULSETIME "PulseTime"
|
||||
|
|
|
@ -857,9 +857,7 @@ typedef struct {
|
|||
uint16_t flowratemeter_calibration[2];// F78
|
||||
int32_t energy_kWhexport_ph[3]; // F7C
|
||||
uint32_t eth_ipv4_address[5]; // F88
|
||||
|
||||
uint32_t ex_energy_kWhtotal; // F9C
|
||||
|
||||
uint32_t power_lock; // F9C
|
||||
SBitfield1 sbflag1; // FA0
|
||||
TeleinfoCfg teleinfo; // FA4
|
||||
uint64_t rf_protocol_mask; // FA8
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
|
||||
#define TASMOTA_SHA_SHORT // Filled by Github sed
|
||||
|
||||
const uint32_t TASMOTA_VERSION = 0x0D040003; // 13.4.0.3
|
||||
const uint32_t TASMOTA_VERSION = 0x0D040004; // 13.4.0.4
|
||||
|
||||
#endif // _TASMOTA_VERSION_H_
|
||||
|
|
|
@ -46,7 +46,7 @@ void RtcSettingsSave(void) {
|
|||
memset(&RtcSettings, 0, sizeof(RtcSettings));
|
||||
RtcSettings.valid = RTC_MEM_VALID;
|
||||
// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
|
||||
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
|
||||
// RtcSettings.ex_energy_kWhtotal = Settings->power_lock;
|
||||
for (uint32_t i = 0; i < 3; i++) {
|
||||
RtcSettings.energy_kWhtoday_ph[i] = Settings->energy_kWhtoday_ph[i];
|
||||
RtcSettings.energy_kWhtotal_ph[i] = Settings->energy_kWhtotal_ph[i];
|
||||
|
@ -1639,7 +1639,7 @@ void SettingsDelta(void) {
|
|||
memset(&Settings->sensors, 0xFF, 16); // Enable all possible sensors
|
||||
}
|
||||
if (Settings->version < 0x09050004) {
|
||||
Settings->ex_energy_kWhtotal = Settings->ipv4_address[4];
|
||||
Settings->power_lock = Settings->ipv4_address[4];
|
||||
ParseIPv4(&Settings->ipv4_address[4], PSTR(WIFI_DNS2));
|
||||
}
|
||||
if (Settings->version < 0x09050005) {
|
||||
|
@ -1664,7 +1664,7 @@ void SettingsDelta(void) {
|
|||
if (Settings->version < 0x09050009) { // 9.5.0.9
|
||||
memset(&Settings->energy_kWhtoday_ph, 0, 36);
|
||||
memset(&RtcSettings.energy_kWhtoday_ph, 0, 24);
|
||||
Settings->energy_kWhtotal_ph[0] = Settings->ex_energy_kWhtotal;
|
||||
Settings->energy_kWhtotal_ph[0] = Settings->power_lock;
|
||||
Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
|
||||
Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2; // = ex_energy_kWhyesterday
|
||||
RtcSettings.energy_kWhtoday_ph[0] = RtcSettings.ex_energy_kWhtoday;
|
||||
|
@ -1773,6 +1773,9 @@ void SettingsDelta(void) {
|
|||
}
|
||||
#endif
|
||||
*/
|
||||
if (Settings->version < 0x0D040004) { // 13.4.0.4
|
||||
Settings->power_lock = 0;
|
||||
}
|
||||
|
||||
Settings->version = TASMOTA_VERSION;
|
||||
SettingsSave(1);
|
||||
|
|
|
@ -23,7 +23,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
|
|||
// Other commands
|
||||
D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_RESTART "|"
|
||||
#ifndef FIRMWARE_MINIMAL_ONLY
|
||||
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_TIMEDPOWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_SLEEP "|"
|
||||
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_POWERLOCK "|" D_CMND_TIMEDPOWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_SLEEP "|"
|
||||
D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SAVEDATA "|"
|
||||
D_CMND_SO "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|" D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|"
|
||||
D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_FREQUENCY_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_WEIGHT_RESOLUTION "|"
|
||||
|
@ -63,7 +63,7 @@ SO_SYNONYMS(kTasmotaSynonyms,
|
|||
void (* const TasmotaCommand[])(void) PROGMEM = {
|
||||
&CmndUpgrade, &CmndUpgrade, &CmndOtaUrl, &CmndSeriallog, &CmndRestart,
|
||||
#ifndef FIRMWARE_MINIMAL_ONLY
|
||||
&CmndBacklog, &CmndDelay, &CmndPower, &CmndTimedPower, &CmndStatus, &CmndState, &CmndSleep,
|
||||
&CmndBacklog, &CmndDelay, &CmndPower, &CmndPowerLock, &CmndTimedPower, &CmndStatus, &CmndState, &CmndSleep,
|
||||
&CmndPowerOnState, &CmndPulsetime, &CmndBlinktime, &CmndBlinkcount, &CmndSavedata,
|
||||
&CmndSetoption, &CmndSetoption, &CmndTemperatureResolution, &CmndHumidityResolution, &CmndPressureResolution, &CmndPowerResolution,
|
||||
&CmndVoltageResolution, &CmndFrequencyResolution, &CmndCurrentResolution, &CmndEnergyResolution, &CmndWeightResolution,
|
||||
|
@ -658,6 +658,26 @@ void CmndPower(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CmndPowerLock(void) {
|
||||
// PowerLock - Show current state
|
||||
// PowerLock0 0 - Reset all power locks
|
||||
// PowerLock0 1 - Set all power locks
|
||||
// PowerLock1 1 - Set Power1 lock
|
||||
if (XdrvMailbox.index <= TasmotaGlobal.devices_present) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
XdrvMailbox.payload &= 1;
|
||||
if (0 == XdrvMailbox.index) { // Control all bits
|
||||
Settings->power_lock = (XdrvMailbox.payload) ? (1 << TasmotaGlobal.devices_present) -1 : 0;
|
||||
} else { // Control individual bits
|
||||
bitWrite(Settings->power_lock, XdrvMailbox.index -1, XdrvMailbox.payload & 1);
|
||||
}
|
||||
}
|
||||
char stemp1[33];
|
||||
ext_snprintf_P(stemp1, sizeof(stemp1), PSTR("%*_b"), TasmotaGlobal.devices_present, Settings->power_lock);
|
||||
ResponseCmndChar(stemp1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -693,9 +693,9 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source)
|
|||
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
if (IsModuleIfan()) {
|
||||
TasmotaGlobal.blink_mask &= 1; // No blinking on the fan relays
|
||||
Settings->flag.interlock = 0; // No interlock mode as it is already done by the microcontroller - CMND_INTERLOCK - Enable/disable interlock
|
||||
Settings->pulse_timer[1] = 0; // No pulsetimers on the fan relays
|
||||
TasmotaGlobal.blink_mask &= 1; // No blinking on the fan relays
|
||||
Settings->flag.interlock = 0; // No interlock mode as it is already done by the microcontroller - CMND_INTERLOCK - Enable/disable interlock
|
||||
Settings->pulse_timer[1] = 0; // No pulsetimers on the fan relays
|
||||
Settings->pulse_timer[2] = 0;
|
||||
Settings->pulse_timer[3] = 0;
|
||||
}
|
||||
|
@ -703,7 +703,7 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source)
|
|||
|
||||
bool publish_power = true;
|
||||
if ((state >= POWER_OFF_NO_STATE) && (state <= POWER_TOGGLE_NO_STATE)) {
|
||||
state &= 3; // POWER_OFF, POWER_ON or POWER_TOGGLE
|
||||
state &= 3; // POWER_OFF, POWER_ON or POWER_TOGGLE
|
||||
publish_power = false;
|
||||
}
|
||||
|
||||
|
@ -712,26 +712,31 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source)
|
|||
}
|
||||
TasmotaGlobal.active_device = device;
|
||||
|
||||
if (bitRead(Settings->power_lock, device -1)) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("CMD: Power%d is LOCKED"), device);
|
||||
state = POWER_SHOW_STATE; // Only show state. Make no change
|
||||
}
|
||||
|
||||
if (state != POWER_SHOW_STATE) {
|
||||
SetPulseTimer((device -1) % MAX_PULSETIMERS, 0);
|
||||
}
|
||||
|
||||
static bool interlock_mutex = false; // Interlock power command pending
|
||||
power_t mask = 1 << (device -1); // Device to control
|
||||
static bool interlock_mutex = false; // Interlock power command pending
|
||||
power_t mask = 1 << (device -1); // Device to control
|
||||
if (state <= POWER_TOGGLE) {
|
||||
if ((TasmotaGlobal.blink_mask & mask)) {
|
||||
TasmotaGlobal.blink_mask &= (POWER_MASK ^ mask); // Clear device mask
|
||||
MqttPublishPowerBlinkState(device);
|
||||
}
|
||||
|
||||
if (Settings->flag.interlock && // CMND_INTERLOCK - Enable/disable interlock
|
||||
if (Settings->flag.interlock && // CMND_INTERLOCK - Enable/disable interlock
|
||||
!interlock_mutex &&
|
||||
((POWER_ON == state) || ((POWER_TOGGLE == state) && !(TasmotaGlobal.power & mask)))
|
||||
) {
|
||||
interlock_mutex = true; // Clear all but masked relay in interlock group if new set requested
|
||||
interlock_mutex = true; // Clear all but masked relay in interlock group if new set requested
|
||||
bool perform_interlock_delay = false;
|
||||
for (uint32_t i = 0; i < MAX_INTERLOCKS; i++) {
|
||||
if (Settings->interlock[i] & mask) { // Find interlock group
|
||||
if (Settings->interlock[i] & mask) { // Find interlock group
|
||||
for (uint32_t j = 0; j < TasmotaGlobal.devices_present; j++) {
|
||||
power_t imask = 1 << j;
|
||||
if ((Settings->interlock[i] & imask) && (TasmotaGlobal.power & imask) && (mask != imask)) {
|
||||
|
@ -739,11 +744,11 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source)
|
|||
perform_interlock_delay = true;
|
||||
}
|
||||
}
|
||||
break; // An interlocked relay is only present in one group so quit
|
||||
break; // An interlocked relay is only present in one group so quit
|
||||
}
|
||||
}
|
||||
if (perform_interlock_delay) {
|
||||
delay(50); // Add some delay to make sure never have more than one relay on
|
||||
delay(50); // Add some delay to make sure never have more than one relay on
|
||||
}
|
||||
interlock_mutex = false;
|
||||
}
|
||||
|
@ -791,7 +796,7 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source)
|
|||
}
|
||||
TasmotaGlobal.blink_timer = millis() + 100;
|
||||
TasmotaGlobal.blink_counter = ((!Settings->blinkcount) ? 64000 : (Settings->blinkcount *2)) +1;
|
||||
TasmotaGlobal.blink_mask |= mask; // Set device mask
|
||||
TasmotaGlobal.blink_mask |= mask; // Set device mask
|
||||
MqttPublishPowerBlinkState(device);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue