added vars: - $mqtt_client - $shortName - $name

* exp

* fix

* Update cmd_tasmota.c
This commit is contained in:
openshwprojects
2025-12-03 09:59:37 +01:00
committed by GitHub
parent 3f8677f110
commit 2898d57ed5
9 changed files with 126 additions and 29 deletions

View File

@ -326,7 +326,7 @@ int be_get(bvm *vm) {
const char *name = be_tostring(vm, 1);
if (name[0] == '$') {
float ret;
CMD_ExpandConstant(name, 0, &ret);
CMD_ExpandConstantFloat(name, 0, &ret);
be_pushreal(vm, ret);
be_return(vm);
}

View File

@ -582,7 +582,7 @@ static int g_totalConstants = sizeof(g_constants) / sizeof(g_constants[0]);
// Etc etc
// Returns true if constant matches
// Returns false if no constants found
const char *CMD_ExpandConstant(const char *s, const char *stop, float *out) {
const char *CMD_ExpandConstantFloat(const char *s, const char *stop, float *out) {
#if ENABLE_EXPAND_CONSTANT
const constant_t *var;
int i;
@ -592,7 +592,7 @@ const char *CMD_ExpandConstant(const char *s, const char *stop, float *out) {
const char *ret = strCompareBound(s, var->constantName, stop, bAllowWildCard);
if (ret) {
*out = var->getValue(s);
ADDLOG_IF_MATHEXP_DBG(LOG_FEATURE_EVENT, "CMD_ExpandConstant: %s", var->name);
ADDLOG_IF_MATHEXP_DBG(LOG_FEATURE_EVENT, "CMD_ExpandConstantFloat: %s", var->name);
return ret;
}
}
@ -611,7 +611,7 @@ byte CMD_ParseOrExpandHexByte(const char **p) {
while (*stop && *stop != '$') {
stop++;
}
CMD_ExpandConstant(*p, stop, &fv);
CMD_ExpandConstantFloat(*p, stop, &fv);
val = fv;
*p = stop;
@ -662,12 +662,13 @@ void SIM_GenerateChannelStatesDesc(char *o, int outLen) {
}
}
}
#endif
const char *CMD_ExpandConstantString(const char *s, const char *stop, char *out, int outLen) {
int idx;
const char *ret;
char tmp[32];
#if WINDOWS
ret = strCompareBound(s, "$autoexec.bat", stop, false);
if (ret) {
byte* data = LFS_ReadFile("autoexec.bat");
@ -728,9 +729,27 @@ const char *CMD_ExpandConstantString(const char *s, const char *stop, char *out,
SIM_GeneratePowerStateDesc(out, outLen);
return ret;
}
#endif
ret = strCompareBound(s, "$mqtt_client", stop, false);
if (ret) {
const char *res = CFG_GetMQTTClientId();
strcpy_safe(out, res, outLen);
return ret;
}
ret = strCompareBound(s, "$shortName", stop, false);
if (ret) {
const char *res = CFG_GetShortDeviceName();
strcpy_safe(out, res, outLen);
return ret;
}
ret = strCompareBound(s, "$name", stop, false);
if (ret) {
const char *res = CFG_GetDeviceName();
strcpy_safe(out, res, outLen);
return ret;
}
return false;
}
#endif
const char* CMD_ExpandConstantToString(const char* constant, char* out, char* stop)
{
@ -742,14 +761,12 @@ const char* CMD_ExpandConstantToString(const char* constant, char* out, char* st
outLen = (stop - out) - 1;
after = CMD_ExpandConstant(constant, 0, &value);
#if WINDOWS
after = CMD_ExpandConstantFloat(constant, 0, &value);
if(after == 0)
{
after = CMD_ExpandConstantString(constant, 0, out, outLen);
return after;
}
#endif
if(after == 0)
return 0;
@ -800,6 +817,17 @@ void CMD_ExpandConstantsWithinString(const char *in, char *out, int outLen) {
}
*out = 0;
}
int CMD_CountVarsInString(const char *in) {
const char *p = in;
int varCount = 0;
while (*p) {
if (*p == '$') {
varCount++;
}
p++;
}
return varCount;
}
// like a strdup, but will expand constants.
// Please remember to free the returned string
char *CMD_ExpandingStrdup(const char *in) {
@ -808,29 +836,25 @@ char *CMD_ExpandingStrdup(const char *in) {
int varCount;
int realLen;
realLen = 0;
varCount = 0;
// I am not sure which approach should I take
// It could be easily done with external buffer, but it would have to be on stack or a global one...
// Maybe let's just assume that variables cannot grow string way too big
p = in;
while (*p) {
if (*p == '$') {
varCount++;
}
realLen++;
p++;
}
realLen = strlen(in);
varCount = CMD_CountVarsInString(in);
// not all var names are short, some are long...
// but $CH1 is short and could expand to something longer like, idk, 123456?
// just to be on safe side....
realLen += varCount * 5;
realLen += varCount * 10;
// space for NULL and also space to be sure
realLen += 2;
ret = (char*)malloc(realLen);
if (ret == 0) {
// malloc failed
return ret;
}
CMD_ExpandConstantsWithinString(in, ret, realLen);
return ret;
}
@ -964,7 +988,7 @@ float CMD_EvaluateExpression(const char *s, const char *stop) {
if (s[0] == '!') {
return !CMD_EvaluateExpression(s + 1, stop);
}
if (CMD_ExpandConstant(s, stop, &c)) {
if (CMD_ExpandConstantFloat(s, stop, &c)) {
return c;
}

View File

@ -75,8 +75,9 @@ commandResult_t CMD_ExecuteCommandArgs(const char* cmd, const char* args, int cm
// like a strdup, but will expand constants.
// Please remember to free the returned string
char* CMD_ExpandingStrdup(const char* in);
int CMD_CountVarsInString(const char *in);
commandResult_t CMD_CreateAliasHelper(const char *alias, const char *ocmd);
const char *CMD_ExpandConstant(const char *s, const char *stop, float *out);
const char *CMD_ExpandConstantFloat(const char *s, const char *stop, float *out);
byte CMD_ParseOrExpandHexByte(const char **p);
enum EventCode {
@ -329,6 +330,7 @@ void SVM_RunThreads(int deltaMS);
void CMD_InitScripting();
void SVM_RunStartupCommandAsScript();
byte* LFS_ReadFile(const char* fname);
byte* LFS_ReadFileExpanding(const char* fname);
int LFS_WriteFile(const char *fname, const byte *data, int len, bool bAppend);
commandResult_t CMD_ClearAllHandlers(const void* context, const char* cmd, const char* args, int cmdFlags);

View File

@ -270,6 +270,19 @@ byte *LFS_ReadFile(const char *fname) {
#endif
return 0;
}
byte* LFS_ReadFileExpanding(const char* fname) {
byte *d = LFS_ReadFile(fname);
if (d == 0)
return 0;
const char *s = (const char *)d;
int vars = CMD_CountVarsInString(s);
if (vars == 0) {
return d;
}
char *r = CMD_ExpandingStrdup(s);
free(d);
return (byte*)r;
}
int LFS_WriteFile(const char *fname, const byte *data, int len, bool bAppend) {
#if ENABLE_LITTLEFS
init_lfs(1);

View File

@ -123,7 +123,7 @@ const char *Tokenizer_GetArgExpanding(int i) {
else {
float f;
int iValue;
CMD_ExpandConstant(tconst, 0, &f);
CMD_ExpandConstantFloat(tconst, 0, &f);
iValue = f;
sprintf(convert, "%i", iValue);
strcat_safe(Templine, convert, sizeof(Templine));
@ -184,7 +184,7 @@ const char *Tokenizer_GetArg(int i) {
else {
float f;
int iValue;
CMD_ExpandConstant(s, 0, &f);
CMD_ExpandConstantFloat(s, 0, &f);
iValue = f;
sprintf(g_argsExpanded[i], "%i", iValue);
}

View File

@ -1555,7 +1555,7 @@ commandResult_t MQTT_PublishFile(const void* context, const char* cmd, const cha
int flags = 0;
byte*data;
Tokenizer_TokenizeString(args, TOKENIZER_ALLOW_QUOTES | TOKENIZER_ALLOW_ESCAPING_QUOTATIONS);
Tokenizer_TokenizeString(args, TOKENIZER_ALLOW_QUOTES | TOKENIZER_ALLOW_ESCAPING_QUOTATIONS | TOKENIZER_EXPAND_EARLY);
if (Tokenizer_GetArgsCount() < 2) {
addLogAdv(LOG_INFO, LOG_FEATURE_MQTT, "Publish command requires two arguments (topic and value)");
@ -1567,7 +1567,7 @@ commandResult_t MQTT_PublishFile(const void* context, const char* cmd, const cha
if (Tokenizer_GetArgIntegerDefault(2, 0) != 0) {
flags = OBK_PUBLISH_FLAG_RAW_TOPIC_NAME;
}
data = LFS_ReadFile(fname);
data = LFS_ReadFileExpanding(fname);
if (data) {
ret = MQTT_PublishMain_StringString(topic, (const char*)data, flags);
free(data);

View File

@ -33,6 +33,9 @@ void Test_HTTP_Client() {
Sim_RunSeconds(5, true);
SELFTEST_ASSERT_CHANNEL(1, 1);
#endif
//CMD_ExecuteCommand("SendGet http://127.0.0.1/cm?cmnd=POWER%20TOGGLE", 0);
//Sim_RunFrames(15, false);
//SELFTEST_ASSERT_CHANNEL(1, 1);
}

View File

@ -515,6 +515,61 @@ void Test_MQTT_Misc() {
SIM_ClearOBK(0);
SIM_ClearAndPrepareForMQTTTesting("miscDevice", "bekens");
CMD_ExecuteCommand("publish homeassistant/test/laaa payload 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/test/laaa", "payload", false);
SIM_ClearMQTTHistory();
// var in topic
CMD_ExecuteCommand("publish homeassistant/$mqtt_client/laaa payload 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/miscDevice/laaa", "payload", false);
SIM_ClearMQTTHistory();
// var in payload
CMD_ExecuteCommand("publish homeassistant/hey/laaa $mqtt_client 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/hey/laaa", "miscDevice", false);
// var in payload
CMD_ExecuteCommand("publish homeassistant/hey/laaa my_name_is_$mqtt_client 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/hey/laaa", "my_name_is_miscDevice", false);
SIM_ClearMQTTHistory();
CMD_ExecuteCommand("publish homeassistant/hey/laaa my_name_is_$mqtt_client 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/hey/laaa", "my_name_is_miscDevice", false);
SIM_ClearMQTTHistory();
CMD_ExecuteCommand("publish homeassistant/cover/$mqtt_client/config {\"name\":\"$mqtt_client\"} 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/cover/miscDevice/config", "{\"name\":\"miscDevice\"}", false);
SIM_ClearMQTTHistory();
CMD_ExecuteCommand("publish homeassistant/cover/$mqtt_client/config {\"name\":\"$mqtt_client\",\"uniq_id\":\"$mqtt_client\",\"~\":\"$mqtt_client\",\"dev_cla\":\"shutter\",\"cmd_t\":\"~/backlog\",\"stat_t\":\"~/shutterState/get\",\"pl_open\":\"OPEN\",\"pl_cls\":\"CLOSE\",\"pl_stop\":\"STOP\",\"stat_o\":\"open\",\"stat_c\":\"closed\"} 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/cover/miscDevice/config", "{\"name\":\"miscDevice\",\"uniq_id\":\"miscDevice\",\"~\":\"miscDevice\",\"dev_cla\":\"shutter\",\"cmd_t\":\"~/backlog\",\"stat_t\":\"~/shutterState/get\",\"pl_open\":\"OPEN\",\"pl_cls\":\"CLOSE\",\"pl_stop\":\"STOP\",\"stat_o\":\"open\",\"stat_c\":\"closed\"}", false);
SIM_ClearMQTTHistory();
CMD_ExecuteCommand("lfs_format", 0);
// send file content as POST to REST interface
Test_FakeHTTPClientPacket_POST("api/lfs/unitTestFile.txt", "filetext");
// get this file
CMD_ExecuteCommand("publishFile homeassistant/cover/$mqtt_client/config unitTestFile.txt 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/cover/miscDevice/config", "filetext", false);
SIM_ClearMQTTHistory();
CMD_ExecuteCommand("lfs_format", 0);
// send file content as POST to REST interface
Test_FakeHTTPClientPacket_POST("api/lfs/unitTestFile.txt", "My name is $mqtt_client");
// get this file
CMD_ExecuteCommand("publishFile homeassistant/cover/$mqtt_client/config unitTestFile.txt 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/cover/miscDevice/config", "My name is miscDevice", false);
SIM_ClearMQTTHistory();
CMD_ExecuteCommand("lfs_format", 0);
CMD_ExecuteCommand("SetChannel 5 123", 0);
// send file content as POST to REST interface
Test_FakeHTTPClientPacket_POST("api/lfs/unitTestFile.txt", "My name is $mqtt_client $CH5");
// get this file
CMD_ExecuteCommand("publishFile homeassistant/cover/$mqtt_client/config unitTestFile.txt 1", 0);
SELFTEST_ASSERT_HAD_MQTT_PUBLISH_STR("homeassistant/cover/miscDevice/config", "My name is miscDevice 123", false);
SIM_ClearMQTTHistory();
CMD_ExecuteCommand("addEventHandler OnChannelChange 5 publish myMagicResult $CH5", 0);
// set channel 5 to 50 and see what we get
SIM_SendFakeMQTTAndRunSimFrame_CMND("setChannel", "5 50");

View File

@ -203,6 +203,8 @@ void Win_DoUnitTests()
{
// SELFTEST_ASSERT_EXPRESSION("sqrt(4)", 2)
Test_MQTT();
Test_HTTP_Client();
// Test_PartitionSearch();
Test_OpenWeatherMap();
Test_MAX72XX();
@ -227,7 +229,6 @@ void Win_DoUnitTests()
Test_Backlog();
Test_DoorSensor();
Test_Command_If_Else();
Test_MQTT();
Test_ChargeLimitDriver();
#if ENABLE_BL_SHARED
Test_EnergyMeter();
@ -276,7 +277,6 @@ void Win_DoUnitTests()
Test_NTP();
Test_NTP_DST();
Test_NTP_SunsetSunrise();
Test_HTTP_Client();
Test_ExpandConstant();
Test_ChangeHandlers_MQTT();
Test_ChangeHandlers();