From 714f938c05c08fab7cf368842480beb892ce1e1d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 1 Aug 2019 15:46:12 +0200 Subject: [PATCH] Refactor energy commands * Refactor energy commands * Add define USE_ENERGY_MARGIN_DETECTION to disable Energy Margin and Power Limit detection * Add define USE_ENERGY_POWER_LIMIT to disable Energy Power Limit detection while Energy Margin detection is active --- sonoff/_changelog.ino | 2 + sonoff/my_user_config.h | 2 + sonoff/support.ino | 11 +- sonoff/support_command.ino | 25 +- sonoff/xdrv_01_webserver.ino | 6 +- sonoff/xdrv_02_mqtt.ino | 7 +- sonoff/xdrv_03_energy.ino | 464 ++++++++++++++++++++--------------- 7 files changed, 292 insertions(+), 225 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 8bafef329..61ddb795b 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -5,6 +5,8 @@ * Add support for MAX31865 Thermocouple sensor by Alberto Lopez Siemens * Add option 0 to Width1 (Marker), Width2 (Second), Width3 (Minute) and Width4 (Hour) disabling display (#6152) * Add MqttCount metric to STATE (#6155) + * Add define USE_ENERGY_MARGIN_DETECTION to disable Energy Margin and Power Limit detection + * Add define USE_ENERGY_POWER_LIMIT to disable Energy Power Limit detection while Energy Margin detection is active * * 6.6.0.2 20190714 * Change commands Var and Mem to show all parameters when no index is given (#6107) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index d14d5ce6c..213641b26 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -417,6 +417,8 @@ // #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) // Power monitoring sensors ----------------------- +#define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) + #define USE_ENERGY_POWER_LIMIT // Add additional support for Energy Power Limit detection (+1k2 code) #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) #define USE_PZEM_AC // Add support for PZEM014,016 Energy monitor (+1k1 code) #define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code) diff --git a/sonoff/support.ino b/sonoff/support.ino index b32658737..be47be883 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -715,9 +715,16 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl return result; } -int GetCommand(const char* haystack) +bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void)) { - return GetCommandCode(XdrvMailbox.command, CMDSZ, XdrvMailbox.topic, haystack); + bool result = false; + + int command_code = GetCommandCode(XdrvMailbox.command, CMDSZ, XdrvMailbox.topic, haystack); + if (command_code >= 0) { + MyCommand[command_code](); + result = true; + } + return result; } int GetStateNumber(char *state_text) diff --git a/sonoff/support_command.ino b/sonoff/support_command.ino index 9083e816f..c05731545 100644 --- a/sonoff/support_command.ino +++ b/sonoff/support_command.ino @@ -31,6 +31,7 @@ const char kTasmotaCommands[] PROGMEM = D_CMND_I2CSCAN "|" #endif D_CMND_SENSOR "|" D_CMND_DRIVER; + void (* const TasmotaCommand[])(void) PROGMEM = { &CmndBacklog, &CmndDelay, &CmndPower, &CmndStatus, &CmndState, &CmndSleep, &CmndUpgrade, &CmndUpgrade, &CmndOtaUrl, &CmndSeriallog, &CmndRestart, &CmndPowerOnState, &CmndPulsetime, &CmndBlinktime, &CmndBlinkcount, &CmndSavedata, @@ -40,7 +41,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport, &CmndSerialSend, &CmndBaudrate, &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, - &CmndTimeStd, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, + &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, #ifdef USE_I2C &CmndI2cScan, #endif @@ -152,10 +153,7 @@ void CommandHandler(char* topic, uint8_t* data, uint32_t data_len) XdrvMailbox.topic = type; XdrvMailbox.data = dataBuf; - int command_code = GetCommand(kTasmotaCommands); - if (command_code >= 0) { - TasmotaCommand[command_code](); - } else { + if (!DecodeCommand(kTasmotaCommands, TasmotaCommand)) { if (!XdrvCall(FUNC_COMMAND)) { if (!XsnsCall(FUNC_COMMAND)) { type = nullptr; // Unknown command @@ -328,6 +326,7 @@ void CmndStatus(void) MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "7")); } +#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_MARGIN_DETECTION) if (energy_flg) { 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,\"" D_CMND_VOLTAGELOW "\":%d,\"" D_CMND_VOLTAGEHIGH "\":%d,\"" D_CMND_CURRENTLOW "\":%d,\"" D_CMND_CURRENTHIGH "\":%d}}"), @@ -335,6 +334,7 @@ void CmndStatus(void) MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "9")); } } +#endif // USE_ENERGY_MARGIN_DETECTION if ((0 == payload) || (8 == payload) || (10 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":")); @@ -1227,12 +1227,9 @@ void CmndTimezone(void) } } -void CmndTimeStd(void) +void CmndTimeStdDst(uint32_t ts) { // TimeStd 0/1, 0/1/2/3/4, 1..12, 1..7, 0..23, +/-780 - uint32_t ts = 0; - if (!strcmp_P(XdrvMailbox.command, PSTR(D_CMND_TIMEDST))) { ts = 1; } - if (XdrvMailbox.data_len > 0) { if (strstr(XdrvMailbox.data, ",") != nullptr) { // Process parameter entry uint32_t tpos = 0; // Parameter index @@ -1271,6 +1268,16 @@ void CmndTimeStd(void) XdrvMailbox.command, Settings.tflag[ts].hemis, Settings.tflag[ts].week, Settings.tflag[ts].month, Settings.tflag[ts].dow, Settings.tflag[ts].hour, Settings.toffset[ts]); } +void CmndTimeStd(void) +{ + CmndTimeStdDst(0); +} + +void CmndTimeDst(void) +{ + CmndTimeStdDst(1); +} + void CmndAltitude(void) { if ((XdrvMailbox.data_len > 0) && ((XdrvMailbox.payload >= -30000) && (XdrvMailbox.payload <= 30000))) { diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index b3cde69f8..9cb1e5139 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -2578,11 +2578,7 @@ bool Xdrv01(uint8_t function) #endif // USE_EMULATION break; case FUNC_COMMAND: - int command_code = GetCommand(kWebCommands); - if (command_code >= 0) { - WebCommand[command_code](); - result = true; - } + result = DecodeCommand(kWebCommands, WebCommand); break; } return result; diff --git a/sonoff/xdrv_02_mqtt.ino b/sonoff/xdrv_02_mqtt.ino index 54b829bc3..13dab5719 100644 --- a/sonoff/xdrv_02_mqtt.ino +++ b/sonoff/xdrv_02_mqtt.ino @@ -36,6 +36,7 @@ const char kMqttCommands[] PROGMEM = D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTCLIENT "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|" D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ; + void (* const MqttCommand[])(void) PROGMEM = { #if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT) &CmndMqttFingerprint, @@ -1058,11 +1059,7 @@ bool Xdrv02(uint8_t function) break; #endif // USE_WEBSERVER case FUNC_COMMAND: - int command_code = GetCommand(kMqttCommands); - if (command_code >= 0) { - MqttCommand[command_code](); - result = true; - } + result = DecodeCommand(kMqttCommands, MqttCommand); break; } } diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index ca6c900c4..cba5f7173 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -25,12 +25,12 @@ #define XDRV_03 3 #define XSNS_03 3 +//#define USE_ENERGY_MARGIN_DETECTION +// #define USE_ENERGY_POWER_LIMIT + #define ENERGY_NONE 0 - #define ENERGY_WATCHDOG 4 // Allow up to 4 seconds before deciding no valid data present -#define FEATURE_POWER_LIMIT true - #include #define D_CMND_POWERCAL "PowerCal" @@ -38,21 +38,34 @@ #define D_CMND_CURRENTCAL "CurrentCal" enum EnergyCommands { - CMND_POWERDELTA, - CMND_POWERLOW, CMND_POWERHIGH, CMND_VOLTAGELOW, CMND_VOLTAGEHIGH, CMND_CURRENTLOW, CMND_CURRENTHIGH, CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL, - CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, - CMND_ENERGYRESET, CMND_MAXENERGY, CMND_MAXENERGYSTART, - CMND_MAXPOWER, CMND_MAXPOWERHOLD, CMND_MAXPOWERWINDOW, - CMND_SAFEPOWER, CMND_SAFEPOWERHOLD, CMND_SAFEPOWERWINDOW }; + CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET }; + const char kEnergyCommands[] PROGMEM = - D_CMND_POWERDELTA "|" - D_CMND_POWERLOW "|" D_CMND_POWERHIGH "|" D_CMND_VOLTAGELOW "|" D_CMND_VOLTAGEHIGH "|" D_CMND_CURRENTLOW "|" D_CMND_CURRENTHIGH "|" D_CMND_POWERCAL "|" D_CMND_VOLTAGECAL "|" D_CMND_CURRENTCAL "|" D_CMND_POWERSET "|" D_CMND_VOLTAGESET "|" D_CMND_CURRENTSET "|" D_CMND_FREQUENCYSET "|" - D_CMND_ENERGYRESET "|" D_CMND_MAXENERGY "|" D_CMND_MAXENERGYSTART "|" +#ifdef USE_ENERGY_MARGIN_DETECTION + D_CMND_POWERDELTA "|" D_CMND_POWERLOW "|" D_CMND_POWERHIGH "|" D_CMND_VOLTAGELOW "|" D_CMND_VOLTAGEHIGH "|" D_CMND_CURRENTLOW "|" D_CMND_CURRENTHIGH "|" +#ifdef USE_ENERGY_POWER_LIMIT + D_CMND_MAXENERGY "|" D_CMND_MAXENERGYSTART "|" D_CMND_MAXPOWER "|" D_CMND_MAXPOWERHOLD "|" D_CMND_MAXPOWERWINDOW "|" - D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW ; + D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW "|" +#endif // USE_ENERGY_POWER_LIMIT +#endif // USE_ENERGY_MARGIN_DETECTION + D_CMND_ENERGYRESET ; + +void (* const EnergyCommand[])(void) PROGMEM = { + &CmndPowerCal, &CmndVoltageCal, &CmndCurrentCal, + &CmndPowerSet, &CmndVoltageSet, &CmndCurrentSet, &CmndFrequencySet, +#ifdef USE_ENERGY_MARGIN_DETECTION + &CmndPowerDelta, &CmndPowerLow, &CmndPowerHigh, &CmndVoltageLow, &CmndVoltageHigh, &CmndCurrentLow, &CmndCurrentHigh, +#ifdef USE_ENERGY_POWER_LIMIT + &CmndMaxEnergy, &CmndMaxEnergyStart, + &CmndMaxPower, &CmndMaxPowerHold, &CmndMaxPowerWindow, + &CmndSafePower, &CmndSafePowerHold, &CmndSafePowerWindow, +#endif // USE_ENERGY_POWER_LIMIT +#endif // USE_ENERGY_MARGIN_DETECTION + &CmndEnergyReset }; float energy_voltage = 0; // 123.1 V float energy_current = 0; // 123.123 A @@ -69,8 +82,7 @@ unsigned long energy_kWhtoday_delta = 0; // 1212312345 Wh 10^-5 (deca micro Wat unsigned long energy_kWhtoday; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = energy_daily unsigned long energy_period = 0; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = energy_daily -float energy_power_last[3] = { 0 }; -uint8_t energy_power_delta = 0; +uint8_t energy_command_code = 0; uint8_t energy_data_valid = 0; bool energy_voltage_available = true; // Enable if voltage is measured @@ -78,26 +90,29 @@ bool energy_current_available = true; // Enable if current is measured bool energy_type_dc = false; bool energy_power_on = true; + +#ifdef USE_ENERGY_MARGIN_DETECTION +float energy_power_last[3] = { 0 }; +uint8_t energy_power_delta = 0; bool energy_min_power_flag = false; bool energy_max_power_flag = false; bool energy_min_voltage_flag = false; bool energy_max_voltage_flag = false; bool energy_min_current_flag = false; bool energy_max_current_flag = false; - uint8_t energy_power_steady_cntr = 8; // Allow for power on stabilization -uint8_t energy_max_energy_state = 0; -#if FEATURE_POWER_LIMIT -uint8_t energy_mplr_counter = 0; +#ifdef USE_ENERGY_POWER_LIMIT uint16_t energy_mplh_counter = 0; uint16_t energy_mplw_counter = 0; -#endif // FEATURE_POWER_LIMIT +uint8_t energy_mplr_counter = 0; +uint8_t energy_max_energy_state = 0; +#endif // USE_ENERGY_POWER_LIMIT +#endif // USE_ENERGY_MARGIN_DETECTION uint8_t energy_fifth_second = 0; Ticker ticker_energy; -int energy_command_code = 0; /********************************************************************************************/ void EnergyUpdateToday(void) @@ -133,11 +148,16 @@ void Energy200ms(void) energy_kWhtoday_delta = 0; energy_period = energy_kWhtoday; EnergyUpdateToday(); +#if defined(USE_ENERGY_MARGIN_DETECTION) && defined(USE_ENERGY_POWER_LIMIT) energy_max_energy_state = 3; +#endif // USE_ENERGY_POWER_LIMIT } +#if defined(USE_ENERGY_MARGIN_DETECTION) && defined(USE_ENERGY_POWER_LIMIT) if ((RtcTime.hour == Settings.energy_max_energy_start) && (3 == energy_max_energy_state)) { energy_max_energy_state = 0; } +#endif // USE_ENERGY_POWER_LIMIT + } } @@ -152,6 +172,7 @@ void EnergySaveState(void) Settings.energy_kWhtotal = RtcSettings.energy_kWhtotal; } +#ifdef USE_ENERGY_MARGIN_DETECTION bool EnergyMargin(bool type, uint16_t margin, uint16_t value, bool &flag, bool &save_flag) { bool change; @@ -167,11 +188,6 @@ bool EnergyMargin(bool type, uint16_t margin, uint16_t value, bool &flag, bool & return (change != save_flag); } -void EnergySetPowerSteadyCounter(void) -{ - energy_power_steady_cntr = 2; -} - void EnergyMarginCheck(void) { uint16_t energy_daily_u = 0; @@ -240,7 +256,7 @@ void EnergyMarginCheck(void) } } -#if FEATURE_POWER_LIMIT +#ifdef USE_ENERGY_POWER_LIMIT // Max Power if (Settings.energy_max_power_limit) { if (energy_active_power > Settings.energy_max_power_limit) { @@ -303,9 +319,9 @@ void EnergyMarginCheck(void) ExecuteCommandPower(1, POWER_OFF, SRC_MAXENERGY); } } -#endif // FEATURE_POWER_LIMIT +#endif // USE_ENERGY_POWER_LIMIT - if (energy_power_delta) EnergyMqttShow(); + if (energy_power_delta) { EnergyMqttShow(); } } void EnergyMqttShow(void) @@ -320,6 +336,7 @@ void EnergyMqttShow(void) MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); energy_power_delta = 0; } +#endif // USE_ENERGY_MARGIN_DETECTION void EnergyOverTempCheck() { @@ -346,70 +363,24 @@ void EnergyOverTempCheck() * Commands \*********************************************************************************************/ -bool EnergyCommand(void) +void EnergyCommandResponse(uint32_t nvalue, uint32_t unit) { - char command [CMDSZ]; - char sunit[CMDSZ]; - bool serviced = true; - bool status_flag = false; - uint8_t unit = 0; - unsigned long nvalue = 0; + if (UNIT_MILLISECOND == unit) { + snprintf_P(XdrvMailbox.command, CMDSZ, PSTR("%sCal"), XdrvMailbox.command); + unit = UNIT_MICROSECOND; + } - int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kEnergyCommands); - energy_command_code = command_code; - if (-1 == command_code) { - serviced = false; // Unknown command + if (Settings.flag.value_units) { + char sunit[CMDSZ]; + Response_P(S_JSON_COMMAND_LVALUE_SPACE_UNIT, XdrvMailbox.command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames)); + } else { + Response_P(S_JSON_COMMAND_LVALUE, XdrvMailbox.command, nvalue); } - else if (CMND_POWERDELTA == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 101)) { - Settings.energy_power_delta = XdrvMailbox.payload; - } - nvalue = Settings.energy_power_delta; - unit = UNIT_PERCENTAGE; - } - else if (CMND_POWERLOW == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_min_power = XdrvMailbox.payload; - } - nvalue = Settings.energy_min_power; - unit = UNIT_WATT; - } - else if (CMND_POWERHIGH == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_max_power = XdrvMailbox.payload; - } - nvalue = Settings.energy_max_power; - unit = UNIT_WATT; - } - else if (CMND_VOLTAGELOW == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 501)) { - Settings.energy_min_voltage = XdrvMailbox.payload; - } - nvalue = Settings.energy_min_voltage; - unit = UNIT_VOLT; - } - else if (CMND_VOLTAGEHIGH == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 501)) { - Settings.energy_max_voltage = XdrvMailbox.payload; - } - nvalue = Settings.energy_max_voltage; - unit = UNIT_VOLT; - } - else if (CMND_CURRENTLOW == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 16001)) { - Settings.energy_min_current = XdrvMailbox.payload; - } - nvalue = Settings.energy_min_current; - unit = UNIT_MILLIAMPERE; - } - else if (CMND_CURRENTHIGH == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 16001)) { - Settings.energy_max_current = XdrvMailbox.payload; - } - nvalue = Settings.energy_max_current; - unit = UNIT_MILLIAMPERE; - } - else if ((CMND_ENERGYRESET == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) { +} + +void CmndEnergyReset(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) { char *p; unsigned long lnum = strtoul(XdrvMailbox.data, &p, 10); if (p != XdrvMailbox.data) { @@ -442,119 +413,200 @@ bool EnergyCommand(void) dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr); Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s}}"), - command, energy_total_chr, energy_yesterday_chr, energy_daily_chr); - status_flag = true; + XdrvMailbox.command, energy_total_chr, energy_yesterday_chr, energy_daily_chr); } - else if ((CMND_POWERCAL == command_code) && XnrgCall(FUNC_COMMAND)) { // microseconds - if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload < 32001)) { Settings.energy_power_calibration = XdrvMailbox.payload; } - nvalue = Settings.energy_power_calibration; - unit = UNIT_MICROSECOND; - } - else if ((CMND_VOLTAGECAL == command_code) && XnrgCall(FUNC_COMMAND)) { // microseconds - if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload < 32001)) { Settings.energy_voltage_calibration = XdrvMailbox.payload; } - nvalue = Settings.energy_voltage_calibration; - unit = UNIT_MICROSECOND; - } - else if ((CMND_CURRENTCAL == command_code) && XnrgCall(FUNC_COMMAND)) { // microseconds - if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload < 32001)) { Settings.energy_current_calibration = XdrvMailbox.payload; } - nvalue = Settings.energy_current_calibration; - unit = UNIT_MICROSECOND; - } - else if ((CMND_POWERSET == command_code) && XnrgCall(FUNC_COMMAND)) { // Watt - nvalue = Settings.energy_power_calibration; - unit = UNIT_MILLISECOND; - } - else if ((CMND_VOLTAGESET == command_code) && XnrgCall(FUNC_COMMAND)) { // Volt - nvalue = Settings.energy_voltage_calibration; - unit = UNIT_MILLISECOND; - } - else if ((CMND_CURRENTSET == command_code) && XnrgCall(FUNC_COMMAND)) { // milliAmpere - nvalue = Settings.energy_current_calibration; - unit = UNIT_MILLISECOND; - } - else if ((CMND_FREQUENCYSET == command_code) && XnrgCall(FUNC_COMMAND)) { // Hz - nvalue = Settings.energy_frequency_calibration; - unit = UNIT_MILLISECOND; - } - -#if FEATURE_POWER_LIMIT - else if (CMND_MAXPOWER == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_max_power_limit = XdrvMailbox.payload; - } - nvalue = Settings.energy_max_power_limit; - unit = UNIT_WATT; - } - else if (CMND_MAXPOWERHOLD == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_max_power_limit_hold = (1 == XdrvMailbox.payload) ? MAX_POWER_HOLD : XdrvMailbox.payload; - } - nvalue = Settings.energy_max_power_limit_hold; - unit = UNIT_SECOND; - } - else if (CMND_MAXPOWERWINDOW == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_max_power_limit_window = (1 == XdrvMailbox.payload) ? MAX_POWER_WINDOW : XdrvMailbox.payload; - } - nvalue = Settings.energy_max_power_limit_window; - unit = UNIT_SECOND; - } - else if (CMND_SAFEPOWER == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_max_power_safe_limit = XdrvMailbox.payload; - } - nvalue = Settings.energy_max_power_safe_limit; - unit = UNIT_WATT; - } - else if (CMND_SAFEPOWERHOLD == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_max_power_safe_limit_hold = (1 == XdrvMailbox.payload) ? SAFE_POWER_HOLD : XdrvMailbox.payload; - } - nvalue = Settings.energy_max_power_safe_limit_hold; - unit = UNIT_SECOND; - } - else if (CMND_SAFEPOWERWINDOW == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 1440)) { - Settings.energy_max_power_safe_limit_window = (1 == XdrvMailbox.payload) ? SAFE_POWER_WINDOW : XdrvMailbox.payload; - } - nvalue = Settings.energy_max_power_safe_limit_window; - unit = UNIT_MINUTE; - } - else if (CMND_MAXENERGY == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { - Settings.energy_max_energy = XdrvMailbox.payload; - energy_max_energy_state = 3; - } - nvalue = Settings.energy_max_energy; - unit = UNIT_WATTHOUR; - } - else if (CMND_MAXENERGYSTART == command_code) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 24)) { - Settings.energy_max_energy_start = XdrvMailbox.payload; - } - nvalue = Settings.energy_max_energy_start; - unit = UNIT_HOUR; - } -#endif // FEATURE_POWER_LIMIT - else serviced = false; // Unknown command - - if (serviced && !status_flag) { - - if (UNIT_MILLISECOND == unit) { - snprintf_P(command, sizeof(command), PSTR("%sCal"), command); - unit = UNIT_MICROSECOND; - } - - if (Settings.flag.value_units) { - Response_P(S_JSON_COMMAND_LVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames)); - } else { - Response_P(S_JSON_COMMAND_LVALUE, command, nvalue); - } - } - - return serviced; } +void CmndPowerCal(void) +{ + energy_command_code = CMND_POWERCAL; + if (XnrgCall(FUNC_COMMAND)) { // microseconds + if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload < 32001)) { + Settings.energy_power_calibration = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_power_calibration, UNIT_MICROSECOND); + } +} + +void CmndVoltageCal(void) +{ + energy_command_code = CMND_VOLTAGECAL; + if (XnrgCall(FUNC_COMMAND)) { // microseconds + if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload < 32001)) { + Settings.energy_voltage_calibration = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_voltage_calibration, UNIT_MICROSECOND); + } +} + +void CmndCurrentCal(void) +{ + energy_command_code = CMND_CURRENTCAL; + if (XnrgCall(FUNC_COMMAND)) { // microseconds + if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload < 32001)) { + Settings.energy_current_calibration = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_current_calibration, UNIT_MICROSECOND); + } +} + +void CmndPowerSet(void) +{ + energy_command_code = CMND_POWERSET; + if (XnrgCall(FUNC_COMMAND)) { // Watt + EnergyCommandResponse(Settings.energy_power_calibration, UNIT_MILLISECOND); + } +} + +void CmndVoltageSet(void) +{ + energy_command_code = CMND_VOLTAGESET; + if (XnrgCall(FUNC_COMMAND)) { // Volt + EnergyCommandResponse(Settings.energy_voltage_calibration, UNIT_MILLISECOND); + } +} + +void CmndCurrentSet(void) +{ + energy_command_code = CMND_CURRENTSET; + if (XnrgCall(FUNC_COMMAND)) { // milliAmpere + EnergyCommandResponse(Settings.energy_current_calibration, UNIT_MILLISECOND); + } +} + +void CmndFrequencySet(void) +{ + energy_command_code = CMND_FREQUENCYSET; + if (XnrgCall(FUNC_COMMAND)) { // Hz + EnergyCommandResponse(Settings.energy_frequency_calibration, UNIT_MILLISECOND); + } +} + +#ifdef USE_ENERGY_MARGIN_DETECTION +void CmndPowerDelta(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 101)) { + Settings.energy_power_delta = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_power_delta, UNIT_PERCENTAGE); +} + +void CmndPowerLow(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_min_power = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_min_power, UNIT_WATT); +} + +void CmndPowerHigh(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_max_power = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_power, UNIT_WATT); +} + +void CmndVoltageLow(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 501)) { + Settings.energy_min_voltage = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_min_voltage, UNIT_VOLT); +} + +void CmndVoltageHigh(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 501)) { + Settings.energy_max_voltage = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_voltage, UNIT_VOLT); +} + +void CmndCurrentLow(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 16001)) { + Settings.energy_min_current = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_min_current, UNIT_MILLIAMPERE); +} + +void CmndCurrentHigh(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 16001)) { + Settings.energy_max_current = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_current, UNIT_MILLIAMPERE); +} + +#ifdef USE_ENERGY_POWER_LIMIT +void CmndMaxPower(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_max_power_limit = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_power_limit, UNIT_WATT); +} + +void CmndMaxPowerHold(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_max_power_limit_hold = (1 == XdrvMailbox.payload) ? MAX_POWER_HOLD : XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_power_limit_hold, UNIT_SECOND); +} + +void CmndMaxPowerWindow(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_max_power_limit_window = (1 == XdrvMailbox.payload) ? MAX_POWER_WINDOW : XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_power_limit_window, UNIT_SECOND); +} + +void CmndSafePower(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_max_power_safe_limit = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_power_safe_limit, UNIT_WATT); +} + +void CmndSafePowerHold(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_max_power_safe_limit_hold = (1 == XdrvMailbox.payload) ? SAFE_POWER_HOLD : XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_power_safe_limit_hold, UNIT_SECOND); +} + +void CmndSafePowerWindow(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 1440)) { + Settings.energy_max_power_safe_limit_window = (1 == XdrvMailbox.payload) ? SAFE_POWER_WINDOW : XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_power_safe_limit_window, UNIT_MINUTE); +} + +void CmndMaxEnergy(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + Settings.energy_max_energy = XdrvMailbox.payload; + energy_max_energy_state = 3; + } + EnergyCommandResponse(Settings.energy_max_energy, UNIT_WATTHOUR); +} + +void CmndMaxEnergyStart(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 24)) { + Settings.energy_max_energy_start = XdrvMailbox.payload; + } + EnergyCommandResponse(Settings.energy_max_energy_start, UNIT_HOUR); +} +#endif // USE_ENERGY_POWER_LIMIT +#endif // USE_ENERGY_MARGIN_DETECTION + void EnergyDrvInit(void) { energy_flg = ENERGY_NONE; @@ -741,15 +793,17 @@ bool Xdrv03(uint8_t function) case FUNC_LOOP: XnrgCall(FUNC_LOOP); break; - case FUNC_COMMAND: - result = EnergyCommand(); - break; +#ifdef USE_ENERGY_MARGIN_DETECTION case FUNC_SET_POWER: - EnergySetPowerSteadyCounter(); + energy_power_steady_cntr = 2; break; +#endif // USE_ENERGY_MARGIN_DETECTION case FUNC_SERIAL: result = XnrgCall(FUNC_SERIAL); break; + case FUNC_COMMAND: + result = DecodeCommand(kEnergyCommands, EnergyCommand); + break; } } return result; @@ -765,7 +819,9 @@ bool Xsns03(uint8_t function) EnergySnsInit(); break; case FUNC_EVERY_SECOND: +#ifdef USE_ENERGY_MARGIN_DETECTION EnergyMarginCheck(); +#endif // USE_ENERGY_MARGIN_DETECTION EnergyOverTempCheck(); break; case FUNC_JSON_APPEND: