diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index cad1a2e83..12f47d073 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -828,10 +828,10 @@ #define THERMOSTAT_TEMP_BAND_NO_PEAK_DET 1 // Default temperature band in thenths of degrees celsius within no peak will be detected #define THERMOSTAT_TIME_STD_DEV_PEAK_DET_OK 10 // Default standard deviation in minutes of the oscillation periods within the peak detection is successful -// -- PID and Timeprop ------------------------------ -//#define USE_TIMEPROP // Add support for the timeprop feature (+0k8 code) +// -- PID and Timeprop ------------------------------ // Both together will add +12k1 code +// #define use TIMEPROP // Add support for the timeprop feature (+9k1 code) // For details on the configuration please see the header of tasmota/xdrv_48_timeprop.ino -//#define USE_PID // Add suport for the PID feature (+11k1 code) +// #define USE_PID // Add suport for the PID feature (+11k2 code) // For details on the configuration please see the header of tasmota/xdrv_49_pid.ino // -- End of general directives --------------------- diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino index bddf2653f..5589868de 100644 --- a/tasmota/xdrv_48_timeprop.ino +++ b/tasmota/xdrv_48_timeprop.ino @@ -18,6 +18,7 @@ */ #ifdef USE_TIMEPROP +#ifndef FIRMWARE_MINIMAL /*********************************************************************************************\ * Code to drive one or more relays in a time proportioned manner give a * required power value. @@ -79,7 +80,23 @@ #define TIMEPROP_RELAYS 1, 2 // which relay to control 1:8 * Publish values between 0 and 1 to the topic(s) described above -\*********************************************************************************************/ + * +**/ + + + +#define D_CMND_TIMEPROP "timeprop_" +#define D_CMND_TIMEPROP_SETPOWER "setpower_" // add index no on end (0:8) and data is power 0:1 + +#include "Timeprop.h" + +enum TimepropCommands { CMND_TIMEPROP_SETPOWER }; +const char kTimepropCommands[] PROGMEM = D_CMND_TIMEPROP_SETPOWER; + +static Timeprop timeprops[TIMEPROP_NUM_OUTPUTS]; +static int relayNos[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_RELAYS}; +static long currentRelayStates = 0; // current actual relay states. Bit 0 first relay + #ifndef TIMEPROP_NUM_OUTPUTS #define TIMEPROP_NUM_OUTPUTS 1 // how many outputs to control (with separate alogorithm for each) @@ -103,8 +120,6 @@ #define TIMEPROP_RELAYS 1 // which relay to control 1:8 #endif -#include "Timeprop.h" - struct { Timeprop timeprops[TIMEPROP_NUM_OUTPUTS]; int relay_nos[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_RELAYS}; @@ -162,7 +177,51 @@ void TimepropXdrvPower(void) { /* char *data; */ /* } XdrvMailbox; */ -// To get here post with topic cmnd/timeprop_setpower_n where n is index into Tprop.timeprops 0:7 +// To get here post with topic cmnd/timeprop_setpower_n where n is index into timeprops 0:7 +bool TimepropCommand() +{ + char command [CMDSZ]; + bool serviced = true; + uint8_t ua_prefix_len = strlen(D_CMND_TIMEPROP); // to detect prefix of command + /* + snprintf_P(log_data, sizeof(log_data), "Command called: " + "index: %d data_len: %d payload: %d topic: %s data: %s\n", + XdrvMailbox.index, + XdrvMailbox.data_len, + XdrvMailbox.payload, + (XdrvMailbox.payload >= 0 ? XdrvMailbox.topic : ""), + (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : "")); + + AddLog(LOG_LEVEL_INFO); + */ + if (0 == strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_TIMEPROP), ua_prefix_len)) { + // command starts with timeprop_ + int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + ua_prefix_len, kTimepropCommands); + if (CMND_TIMEPROP_SETPOWER == command_code) { + /* + snprintf_P(log_data, sizeof(log_data), "Timeprop command timeprop_setpower: " + "index: %d data_len: %d payload: %d topic: %s data: %s", + XdrvMailbox.index, + XdrvMailbox.data_len, + XdrvMailbox.payload, + (XdrvMailbox.payload >= 0 ? XdrvMailbox.topic : ""), + (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : "")); + AddLog(LOG_LEVEL_INFO); + */ + if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS) { + timeprops[XdrvMailbox.index].setPower( atof(XdrvMailbox.data), Tprop.current_time_secs ); + } + snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"" D_CMND_TIMEPROP D_CMND_TIMEPROP_SETPOWER "%d\":\"%s\"}"), + XdrvMailbox.index, XdrvMailbox.data); + } + else { + serviced = false; + } + } else { + serviced = false; + } + return serviced; +} /*********************************************************************************************\ * Interface @@ -180,6 +239,9 @@ bool Xdrv48(byte function) { case FUNC_EVERY_SECOND: TimepropEverySecond(); break; + case FUNC_COMMAND: + result = TimepropCommand(); + break; case FUNC_SET_POWER: TimepropXdrvPower(); break; @@ -187,4 +249,5 @@ bool Xdrv48(byte function) { return result; } +#endif // FIRMWARE_MINIMAL #endif // USE_TIMEPROP diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino index 7da87ac7d..15097106b 100644 --- a/tasmota/xdrv_49_pid.ino +++ b/tasmota/xdrv_49_pid.ino @@ -18,6 +18,7 @@ */ #ifdef USE_PID +#ifndef FIRMWARE_MINIMAL /*********************************************************************************************\ * Uses the library https://github.com/colinl/process-control.git from Github * In user_config_override.h include code as follows: @@ -117,11 +118,6 @@ #define PID_REPORT_MORE_SETTINGS // If defined, the SENSOR output will provide more extensive json // output in the PID section -// #define PID_BACKWARD_COMPATIBLE // Preserve the backward compatible reporting of PID power via - // `%topic%/PID {"power":"0.000"}` This is now available in - // `%topic$/SENSOR {..., "PID":{"PidPower":0.00}}` - // Don't use unless you know that you need it - * Help with using the PID algorithm and with loop tuning can be found at * http://blog.clanlaw.org.uk/2018/01/09/PID-tuning-with-node-red-contrib-pid.html * This is directed towards using the algorithm in the node-red node node-red-contrib-pid but the algorithm here is based on @@ -271,26 +267,27 @@ void CmndSetPv(void) { // this runs it at the next second Pid.run_pid_now = true; } + ResponseCmndFloat(atof(XdrvMailbox.data), 1); } void CmndSetSp(void) { Pid.pid.setSp(atof(XdrvMailbox.data)); - ResponseCmndNumber(atof(XdrvMailbox.data)); + ResponseCmndFloat(atof(XdrvMailbox.data), 1); } void CmndSetPb(void) { Pid.pid.setPb(atof(XdrvMailbox.data)); - ResponseCmndNumber(atof(XdrvMailbox.data)); + ResponseCmndFloat(atof(XdrvMailbox.data), 1); } void CmndSetTi(void) { Pid.pid.setTi(atof(XdrvMailbox.data)); - ResponseCmndNumber(atof(XdrvMailbox.data)); + ResponseCmndFloat(atof(XdrvMailbox.data), 1); } void CmndSetTd(void) { Pid.pid.setTd(atof(XdrvMailbox.data)); - ResponseCmndNumber(atof(XdrvMailbox.data)); + ResponseCmndFloat(atof(XdrvMailbox.data), 1); } void CmndSetInitialInt(void) { @@ -300,7 +297,7 @@ void CmndSetInitialInt(void) { void CmndSetDSmooth(void) { Pid.pid.setDSmooth(atof(XdrvMailbox.data)); - ResponseCmndNumber(atof(XdrvMailbox.data)); + ResponseCmndFloat(atof(XdrvMailbox.data), 1); } void CmndSetAuto(void) { @@ -310,7 +307,7 @@ void CmndSetAuto(void) { void CmndSetManualPower(void) { Pid.pid.setManualPower(atof(XdrvMailbox.data)); - ResponseCmndNumber(atof(XdrvMailbox.data)); + ResponseCmndFloat(atof(XdrvMailbox.data), 1); } void CmndSetMaxInterval(void) { @@ -391,14 +388,14 @@ void PIDShowValues(void) { void PIDRun(void) { double power = Pid.pid.tick(Pid.current_time_secs); -#ifdef PID_BACKWARD_COMPATIBLE +#ifdef PID_DONT_USE_PID_TOPIC // This part is left inside to regularly publish the PID Power via // `%topic%/PID {"power":"0.000"}` char str_buf[FLOATSZ]; dtostrfd(power, 3, str_buf); snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s\":\"%s\"}"), "power", str_buf); MqttPublishPrefixTopic_P(TELE, "PID", false); -#endif // PID_BACKWARD_COMPATIBLE +#endif // PID_DONT_USE_PID_TOPIC #if defined PID_SHUTTER // send output as a position from 0-100 to defined shutter @@ -443,4 +440,5 @@ bool Xdrv49(byte function) { } return result; } +#endif //FIRMWARE_MINIMAL #endif // USE_PID