mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 19:56:30 +00:00
Add command `PowerDelta1
to
PowerDelta3
`
- Bump version to 8.4.0.3 - Add command ``PowerDelta1`` to ``PowerDelta3`` to trigger on up to three phases (#9134)
This commit is contained in:
parent
6e111477a0
commit
0f1e4fc917
@ -53,7 +53,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### Version 8.4.0.2
|
### Version 8.4.0.3
|
||||||
|
|
||||||
- Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1
|
- Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1
|
||||||
- Change White blend mode moved to using ``SetOption 105`` instead of ``RGBWWTable``
|
- Change White blend mode moved to using ``SetOption 105`` instead of ``RGBWWTable``
|
||||||
@ -63,6 +63,8 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||||||
- Add command ``Restart 2`` to halt system. Needs hardware reset or power cycle to restart (#9046)
|
- Add command ``Restart 2`` to halt system. Needs hardware reset or power cycle to restart (#9046)
|
||||||
- Add ESP32 Analog input support for GPIO32 to GPIO39
|
- Add ESP32 Analog input support for GPIO32 to GPIO39
|
||||||
- Add Zigbee options to ``ZbSend`` ``Config`` and ``ReadCondig``
|
- Add Zigbee options to ``ZbSend`` ``Config`` and ``ReadCondig``
|
||||||
|
- Add Zigbee web gui widget for Temp/Humidity/Pressure sensors
|
||||||
- Add better config corruption recovery (#9046)
|
- Add better config corruption recovery (#9046)
|
||||||
- Add virtual CT for 4 channels lights, emulating a 5th channel
|
- Add virtual CT for 4 channels lights, emulating a 5th channel
|
||||||
- Add support for DYP ME007 ultrasonic distance sensor by Janusz Kostorz (#9113)
|
- Add support for DYP ME007 ultrasonic distance sensor by Janusz Kostorz (#9113)
|
||||||
|
- Add command ``PowerDelta1`` to ``PowerDelta3`` to trigger on up to three phases (#9134)
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
## Unreleased (development)
|
## Unreleased (development)
|
||||||
|
|
||||||
|
### 8.4.0.3 20200823
|
||||||
|
|
||||||
|
- Add command ``PowerDelta1`` to ``PowerDelta3`` to trigger on up to three phases (#9134)
|
||||||
|
|
||||||
### 8.4.0.2 20200813
|
### 8.4.0.2 20200813
|
||||||
|
|
||||||
- Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1
|
- Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1
|
||||||
|
@ -557,7 +557,7 @@ struct {
|
|||||||
uint16_t dimmer_hw_min; // E90
|
uint16_t dimmer_hw_min; // E90
|
||||||
uint16_t dimmer_hw_max; // E92
|
uint16_t dimmer_hw_max; // E92
|
||||||
uint32_t deepsleep; // E94
|
uint32_t deepsleep; // E94
|
||||||
uint16_t energy_power_delta; // E98
|
uint16_t ex2_energy_power_delta; // E98 - Free since 8.4.0.3
|
||||||
uint8_t shutter_motordelay[MAX_SHUTTERS]; // E9A
|
uint8_t shutter_motordelay[MAX_SHUTTERS]; // E9A
|
||||||
int8_t temp_comp; // E9E
|
int8_t temp_comp; // E9E
|
||||||
uint8_t weight_change; // E9F
|
uint8_t weight_change; // E9F
|
||||||
@ -610,10 +610,14 @@ struct {
|
|||||||
uint8_t tcp_baudrate; // F41
|
uint8_t tcp_baudrate; // F41
|
||||||
uint8_t fallback_module; // F42
|
uint8_t fallback_module; // F42
|
||||||
|
|
||||||
uint8_t free_f43[113]; // F43 - Decrement if adding new Setting variables just above and below
|
uint8_t free_f43[1]; // F43
|
||||||
|
|
||||||
|
uint16_t energy_power_delta[3]; // F44
|
||||||
|
|
||||||
|
uint8_t free_f4e[106]; // F4A - Decrement if adding new Setting variables just above and below
|
||||||
|
|
||||||
// Only 32 bit boundary variables below
|
// Only 32 bit boundary variables below
|
||||||
SysBitfield5 flag5; // EB4
|
SysBitfield5 flag5; // FB4
|
||||||
uint16_t pulse_counter_debounce_low; // FB8
|
uint16_t pulse_counter_debounce_low; // FB8
|
||||||
uint16_t pulse_counter_debounce_high; // FBA
|
uint16_t pulse_counter_debounce_high; // FBA
|
||||||
uint32_t keeloq_master_msb; // FBC
|
uint32_t keeloq_master_msb; // FBC
|
||||||
|
@ -935,7 +935,9 @@ void SettingsDefaultSet2(void)
|
|||||||
flag3.dds2382_model |= ENERGY_DDS2382_MODE;
|
flag3.dds2382_model |= ENERGY_DDS2382_MODE;
|
||||||
flag3.hardware_energy_total |= ENERGY_HARDWARE_TOTALS;
|
flag3.hardware_energy_total |= ENERGY_HARDWARE_TOTALS;
|
||||||
Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY;
|
Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY;
|
||||||
// Settings.energy_power_delta = 0;
|
// Settings.energy_power_delta[0] = 0;
|
||||||
|
// Settings.energy_power_delta[1] = 0;
|
||||||
|
// Settings.energy_power_delta[2] = 0;
|
||||||
Settings.energy_power_calibration = HLW_PREF_PULSE;
|
Settings.energy_power_calibration = HLW_PREF_PULSE;
|
||||||
Settings.energy_voltage_calibration = HLW_UREF_PULSE;
|
Settings.energy_voltage_calibration = HLW_UREF_PULSE;
|
||||||
Settings.energy_current_calibration = HLW_IREF_PULSE;
|
Settings.energy_current_calibration = HLW_IREF_PULSE;
|
||||||
@ -1346,7 +1348,7 @@ void SettingsDelta(void)
|
|||||||
Settings.ex_sbaudrate = 0;
|
Settings.ex_sbaudrate = 0;
|
||||||
*/
|
*/
|
||||||
Settings.flag3.fast_power_cycle_disable = 0;
|
Settings.flag3.fast_power_cycle_disable = 0;
|
||||||
Settings.energy_power_delta = Settings.ex_energy_power_delta;
|
Settings.ex2_energy_power_delta = Settings.ex_energy_power_delta;
|
||||||
Settings.ex_energy_power_delta = 0;
|
Settings.ex_energy_power_delta = 0;
|
||||||
}
|
}
|
||||||
if (Settings.version < 0x06060015) {
|
if (Settings.version < 0x06060015) {
|
||||||
@ -1503,6 +1505,11 @@ void SettingsDelta(void)
|
|||||||
if (Settings.version < 0x08030106) {
|
if (Settings.version < 0x08030106) {
|
||||||
Settings.fallback_module = FALLBACK_MODULE;
|
Settings.fallback_module = FALLBACK_MODULE;
|
||||||
}
|
}
|
||||||
|
if (Settings.version < 0x08040003) {
|
||||||
|
Settings.energy_power_delta[0] = Settings.ex2_energy_power_delta;
|
||||||
|
Settings.energy_power_delta[1] = 0;
|
||||||
|
Settings.energy_power_delta[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Settings.version = VERSION;
|
Settings.version = VERSION;
|
||||||
SettingsSave(1);
|
SettingsSave(1);
|
||||||
|
@ -538,9 +538,9 @@ void CmndStatus(void)
|
|||||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_MARGIN_DETECTION)
|
#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_MARGIN_DETECTION)
|
||||||
if (energy_flg) {
|
if (energy_flg) {
|
||||||
if ((0 == payload) || (9 == payload)) {
|
if ((0 == payload) || (9 == payload)) {
|
||||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERDELTA "\":%d,\"" D_CMND_POWERLOW "\":%d,\"" D_CMND_POWERHIGH "\":%d,\""
|
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERDELTA "\":[%d,%d,%d],\"" D_CMND_POWERLOW "\":%d,\"" D_CMND_POWERHIGH "\":%d,\""
|
||||||
D_CMND_VOLTAGELOW "\":%d,\"" D_CMND_VOLTAGEHIGH "\":%d,\"" D_CMND_CURRENTLOW "\":%d,\"" D_CMND_CURRENTHIGH "\":%d}}"),
|
D_CMND_VOLTAGELOW "\":%d,\"" D_CMND_VOLTAGEHIGH "\":%d,\"" D_CMND_CURRENTLOW "\":%d,\"" D_CMND_CURRENTHIGH "\":%d}}"),
|
||||||
Settings.energy_power_delta, Settings.energy_min_power, Settings.energy_max_power,
|
Settings.energy_power_delta[0], Settings.energy_power_delta[1], Settings.energy_power_delta[2], Settings.energy_min_power, Settings.energy_max_power,
|
||||||
Settings.energy_min_voltage, Settings.energy_max_voltage, Settings.energy_min_current, Settings.energy_max_current);
|
Settings.energy_min_voltage, Settings.energy_max_voltage, Settings.energy_min_current, Settings.energy_max_current);
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "9"));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "9"));
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#ifndef _TASMOTA_VERSION_H_
|
#ifndef _TASMOTA_VERSION_H_
|
||||||
#define _TASMOTA_VERSION_H_
|
#define _TASMOTA_VERSION_H_
|
||||||
|
|
||||||
const uint32_t VERSION = 0x08040002;
|
const uint32_t VERSION = 0x08040003;
|
||||||
|
|
||||||
// Lowest compatible version
|
// Lowest compatible version
|
||||||
const uint32_t VERSION_COMPATIBLE = 0x07010006;
|
const uint32_t VERSION_COMPATIBLE = 0x07010006;
|
||||||
|
@ -108,7 +108,7 @@ struct ENERGY {
|
|||||||
bool power_on = true;
|
bool power_on = true;
|
||||||
|
|
||||||
#ifdef USE_ENERGY_MARGIN_DETECTION
|
#ifdef USE_ENERGY_MARGIN_DETECTION
|
||||||
uint16_t power_history[3] = { 0 };
|
uint16_t power_history[3][3] = {{ 0 }, { 0 }, { 0 }};
|
||||||
uint8_t power_steady_counter = 8; // Allow for power on stabilization
|
uint8_t power_steady_counter = 8; // Allow for power on stabilization
|
||||||
bool min_power_flag = false;
|
bool min_power_flag = false;
|
||||||
bool max_power_flag = false;
|
bool max_power_flag = false;
|
||||||
@ -130,6 +130,31 @@ Ticker ticker_energy;
|
|||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
char* EnergyFormatIndex(char* result, char* input, bool json, uint32_t index, bool single = false)
|
||||||
|
{
|
||||||
|
char layout[16];
|
||||||
|
GetTextIndexed(layout, sizeof(layout), (index -1) + (3 * json), kEnergyPhases);
|
||||||
|
switch (index) {
|
||||||
|
case 2:
|
||||||
|
snprintf_P(result, FLOATSZ *3, layout, input, input + FLOATSZ); // Dirty
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
snprintf_P(result, FLOATSZ *3, layout, input, input + FLOATSZ, input + FLOATSZ + FLOATSZ); // Even dirtier
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf_P(result, FLOATSZ *3, input);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* EnergyFormat(char* result, char* input, bool json, bool single = false)
|
||||||
|
{
|
||||||
|
uint8_t index = (single) ? 1 : Energy.phase_count; // 1,2,3
|
||||||
|
return EnergyFormatIndex(result, input, json, index, single);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
|
||||||
bool EnergyTariff1Active() // Off-Peak hours
|
bool EnergyTariff1Active() // Off-Peak hours
|
||||||
{
|
{
|
||||||
uint8_t dst = 0;
|
uint8_t dst = 0;
|
||||||
@ -303,38 +328,53 @@ void EnergyMarginCheck(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t energy_power_u = (uint16_t)(Energy.active_power[0]);
|
|
||||||
|
|
||||||
bool jsonflg = false;
|
bool jsonflg = false;
|
||||||
Response_P(PSTR("{\"" D_RSLT_MARGINS "\":{"));
|
Response_P(PSTR("{\"" D_RSLT_MARGINS "\":{"));
|
||||||
|
|
||||||
if (Settings.energy_power_delta) {
|
int16_t power_diff[3] = { 0 };
|
||||||
int16_t power_diff = energy_power_u - Energy.power_history[0];
|
for (uint32_t phase = 0; phase < Energy.phase_count; phase++) {
|
||||||
uint16_t delta = abs(power_diff);
|
uint16_t active_power = (uint16_t)(Energy.active_power[phase]);
|
||||||
if (delta > 0) {
|
|
||||||
if (Settings.energy_power_delta < 101) { // 1..100 = Percentage
|
if (Settings.energy_power_delta[phase]) {
|
||||||
uint16_t min_power = (Energy.power_history[0] > energy_power_u) ? energy_power_u : Energy.power_history[0];
|
power_diff[phase] = active_power - Energy.power_history[phase][0];
|
||||||
if (0 == min_power) { min_power++; } // Fix divide by 0 exception (#6741)
|
uint16_t delta = abs(power_diff[phase]);
|
||||||
delta = (delta * 100) / min_power;
|
bool threshold_met = false;
|
||||||
if (delta > Settings.energy_power_delta) {
|
if (delta > 0) {
|
||||||
jsonflg = true;
|
if (Settings.energy_power_delta[phase] < 101) { // 1..100 = Percentage
|
||||||
}
|
uint16_t min_power = (Energy.power_history[phase][0] > active_power) ? active_power : Energy.power_history[phase][0];
|
||||||
} else { // 101..32000 = Absolute
|
if (0 == min_power) { min_power++; } // Fix divide by 0 exception (#6741)
|
||||||
if (delta > (Settings.energy_power_delta -100)) {
|
delta = (delta * 100) / min_power;
|
||||||
jsonflg = true;
|
if (delta > Settings.energy_power_delta[phase]) {
|
||||||
|
threshold_met = true;
|
||||||
|
}
|
||||||
|
} else { // 101..32000 = Absolute
|
||||||
|
if (delta > (Settings.energy_power_delta[phase] -100)) {
|
||||||
|
threshold_met = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jsonflg) {
|
if (threshold_met) {
|
||||||
Energy.power_history[1] = Energy.active_power[0]; // We only want one report so reset history
|
Energy.power_history[phase][1] = active_power; // We only want one report so reset history
|
||||||
Energy.power_history[2] = Energy.active_power[0];
|
Energy.power_history[phase][2] = active_power;
|
||||||
|
jsonflg = true;
|
||||||
ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%d"), power_diff);
|
} else {
|
||||||
|
power_diff[phase] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Energy.power_history[phase][0] = Energy.power_history[phase][1]; // Shift in history every second allowing power changes to settle for up to three seconds
|
||||||
|
Energy.power_history[phase][1] = Energy.power_history[phase][2];
|
||||||
|
Energy.power_history[phase][2] = active_power;
|
||||||
}
|
}
|
||||||
Energy.power_history[0] = Energy.power_history[1]; // Shift in history every second allowing power changes to settle for up to three seconds
|
if (jsonflg) {
|
||||||
Energy.power_history[1] = Energy.power_history[2];
|
char power_diff_chr[Energy.phase_count][FLOATSZ];
|
||||||
Energy.power_history[2] = energy_power_u;
|
for (uint32_t phase = 0; phase < Energy.phase_count; phase++) {
|
||||||
|
dtostrfd(power_diff[phase], 0, power_diff_chr[phase]);
|
||||||
|
}
|
||||||
|
char value_chr[FLOATSZ *3];
|
||||||
|
ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFormat(value_chr, power_diff_chr[0], 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t energy_power_u = (uint16_t)(Energy.active_power[0]);
|
||||||
|
|
||||||
if (Energy.power_on && (Settings.energy_min_power || Settings.energy_max_power || Settings.energy_min_voltage || Settings.energy_max_voltage || Settings.energy_min_current || Settings.energy_max_current)) {
|
if (Energy.power_on && (Settings.energy_min_power || Settings.energy_max_power || Settings.energy_min_voltage || Settings.energy_max_voltage || Settings.energy_min_current || Settings.energy_max_current)) {
|
||||||
uint16_t energy_voltage_u = (uint16_t)(Energy.voltage[0]);
|
uint16_t energy_voltage_u = (uint16_t)(Energy.voltage[0]);
|
||||||
@ -725,10 +765,12 @@ void CmndModuleAddress(void)
|
|||||||
#ifdef USE_ENERGY_MARGIN_DETECTION
|
#ifdef USE_ENERGY_MARGIN_DETECTION
|
||||||
void CmndPowerDelta(void)
|
void CmndPowerDelta(void)
|
||||||
{
|
{
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32000)) {
|
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
|
||||||
Settings.energy_power_delta = XdrvMailbox.payload;
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32000)) {
|
||||||
|
Settings.energy_power_delta[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||||
|
}
|
||||||
|
ResponseCmndIdxNumber(Settings.energy_power_delta[XdrvMailbox.index -1]);
|
||||||
}
|
}
|
||||||
ResponseCmndNumber(Settings.energy_power_delta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndPowerLow(void)
|
void CmndPowerLow(void)
|
||||||
@ -881,29 +923,6 @@ const char HTTP_ENERGY_SNS3[] PROGMEM =
|
|||||||
"{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
"{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
|
|
||||||
char* EnergyFormatIndex(char* result, char* input, bool json, uint32_t index, bool single = false)
|
|
||||||
{
|
|
||||||
char layout[16];
|
|
||||||
GetTextIndexed(layout, sizeof(layout), (index -1) + (3 * json), kEnergyPhases);
|
|
||||||
switch (index) {
|
|
||||||
case 2:
|
|
||||||
snprintf_P(result, FLOATSZ *3, layout, input, input + FLOATSZ); // Dirty
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
snprintf_P(result, FLOATSZ *3, layout, input, input + FLOATSZ, input + FLOATSZ + FLOATSZ); // Even dirtier
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
snprintf_P(result, FLOATSZ *3, input);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* EnergyFormat(char* result, char* input, bool json, bool single = false)
|
|
||||||
{
|
|
||||||
uint8_t index = (single) ? 1 : Energy.phase_count; // 1,2,3
|
|
||||||
return EnergyFormatIndex(result, input, json, index, single);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnergyShow(bool json)
|
void EnergyShow(bool json)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < Energy.phase_count; i++) {
|
for (uint32_t i = 0; i < Energy.phase_count; i++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user