From 74327d96716255f48c3790e2dd166afdad9c56fb Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:29:25 +0200 Subject: [PATCH 1/9] support braces in expressions --- src/cmnds/cmd_if.c | 86 +++++++++++++++++++---------- src/selftest/selftest_expressions.c | 31 +++++++++++ src/win_main.c | 5 +- 3 files changed, 92 insertions(+), 30 deletions(-) diff --git a/src/cmnds/cmd_if.c b/src/cmnds/cmd_if.c index 5f4a2d4c5..05db0f18b 100644 --- a/src/cmnds/cmd_if.c +++ b/src/cmnds/cmd_if.c @@ -86,13 +86,19 @@ const char *CMD_FindOperator(const char *s, const char *stop, byte *oCode) { retVal = 0; bestPriority = 0; - + int level = 0; while (s[0] && s[1] && (s < stop || stop == 0)) { - if (s != signSkip) { + if (*s == '(') { + level++; + } else if (*s == ')') { + level--; + } else if (s != signSkip) { for (o = 0; o < g_numOperators; o++) { if (!strncmp(s, g_operators[o].txt, g_operators[o].len)) { - if (g_operators[o].prio >= bestPriority) { - bestPriority = g_operators[o].prio; + int prio = g_operators[o].prio; + prio -= level * 1000; + if (prio >= bestPriority) { + bestPriority = prio; retVal = s; *oCode = o; signSkip = s + g_operators[o].len; @@ -675,35 +681,35 @@ const char *CMD_ExpandConstantString(const char *s, const char *stop, char *out, #endif const char *CMD_ExpandConstantToString(const char *constant, char *out, char *stop) { - int outLen; - float value; - int valueInt; - const char *after; - float delta; +int outLen; +float value; +int valueInt; +const char *after; +float delta; - outLen = (stop - out) - 1; +outLen = (stop - out) - 1; - after = CMD_ExpandConstant(constant, 0, &value); +after = CMD_ExpandConstant(constant, 0, &value); #if WINDOWS - if (after == 0) { - after = CMD_ExpandConstantString(constant, 0, out, outLen); - return after; - } +if (after == 0) { + after = CMD_ExpandConstantString(constant, 0, out, outLen); + return after; +} #endif - if (after == 0) - return 0; +if (after == 0) +return 0; - valueInt = (int)value; - delta = valueInt - value; - if (delta < 0) - delta = -delta; - if (delta < 0.001f) { - snprintf(out, outLen, "%i", valueInt); - } - else { - snprintf(out, outLen, "%f", value); - } - return after; +valueInt = (int)value; +delta = valueInt - value; +if (delta < 0) + delta = -delta; +if (delta < 0.001f) { + snprintf(out, outLen, "%i", valueInt); +} +else { + snprintf(out, outLen, "%f", value); +} +return after; } void CMD_ExpandConstantsWithinString(const char *in, char *out, int outLen) { char *outStop; @@ -771,6 +777,24 @@ char *CMD_ExpandingStrdup(const char *in) { CMD_ExpandConstantsWithinString(in, ret, realLen); return ret; } +const char *CMD_FindMatchingBrace(const char *s) { + if (*s != '(') + return s; + int level = 1; + s++; + while (*s) { + if (*s == '(') + level++; + else if (*s == ')') { + level--; + if (level == 0) + return s; + } + s++; + } + return s; + +} float CMD_EvaluateExpression(const char *s, const char *stop) { byte opCode; const char *op; @@ -789,12 +813,17 @@ float CMD_EvaluateExpression(const char *s, const char *stop) { while (stop > s && isspace(((int)stop[-1]))) { stop--; } + // cull whitespaces at the start while (isspace(((int)*s))) { s++; if (s >= stop) { return 0; } } + if (*s == '(' && stop[-1] == ')' && CMD_FindMatchingBrace(s) == (stop-1)) { + s++; + stop--; + } if (g_expDebugBuffer == 0) { g_expDebugBuffer = malloc(EXPRESSION_DEBUG_BUFFER_SIZE); } @@ -804,7 +833,6 @@ float CMD_EvaluateExpression(const char *s, const char *stop) { g_expDebugBuffer[idx] = 0; ADDLOG_IF_MATHEXP_DBG(LOG_FEATURE_EVENT, "CMD_EvaluateExpression: will run '%s'", g_expDebugBuffer); } - op = CMD_FindOperator(s, stop, &opCode); if (op) { const char *p2; diff --git a/src/selftest/selftest_expressions.c b/src/selftest/selftest_expressions.c index 60e6a07c6..86d2fcd47 100644 --- a/src/selftest/selftest_expressions.c +++ b/src/selftest/selftest_expressions.c @@ -2,6 +2,36 @@ #include "selftest_local.h" +void Test_Expressions_RunTests_Braces() { + SELFTEST_ASSERT_EXPRESSION("2*(3+3)", 12); + SELFTEST_ASSERT_EXPRESSION("2*(3+7)", 20); + SELFTEST_ASSERT_EXPRESSION("2*(3+4)", 14); + SELFTEST_ASSERT_EXPRESSION("4*(3+4)", 28); + SELFTEST_ASSERT_EXPRESSION("4*(3+4+3)", 40); + SELFTEST_ASSERT_EXPRESSION("9*(2+6+1)", 81); + SELFTEST_ASSERT_EXPRESSION("2*(8+7)", 30); + SELFTEST_ASSERT_EXPRESSION("10*(3+5)", 80); + SELFTEST_ASSERT_EXPRESSION("3*(7+7)", 42); + SELFTEST_ASSERT_EXPRESSION("11*(2+3)", 55); + SELFTEST_ASSERT_EXPRESSION("12*(3+3+3)", 108); + SELFTEST_ASSERT_EXPRESSION("5*(4+5)", 45); + SELFTEST_ASSERT_EXPRESSION("2*((3+5)*2)", 32); + SELFTEST_ASSERT_EXPRESSION("4*(3+(2*5))", 52); + SELFTEST_ASSERT_EXPRESSION("(3*(2+3))*(4+1)", 75); + SELFTEST_ASSERT_EXPRESSION("(2+3)*(4+(5*2))", 70); + SELFTEST_ASSERT_EXPRESSION("((3+2)*(2+1))*2", 30); + SELFTEST_ASSERT_EXPRESSION("4*((2+5)+(3*2))", 52); + SELFTEST_ASSERT_EXPRESSION("2*(3+((4*2)+1))", 24); + SELFTEST_ASSERT_EXPRESSION("((3+4)*(2+2))*2", 56); + SELFTEST_ASSERT_EXPRESSION("(5*(3+(2*2)))+10", 45); + SELFTEST_ASSERT_EXPRESSION("(6+4)*(3+(2*3))", 90); + SELFTEST_ASSERT_EXPRESSION("2*(3+5)+((2+3)*4)", 36); + SELFTEST_ASSERT_EXPRESSION("((4*2)+(3*(2+3)))*2", 46); + SELFTEST_ASSERT_EXPRESSION("((3+4)*(5+6))+((2*3)+4)", 87); + + + +} void Test_Expressions_RunTests_Basic() { // reset whole device SIM_ClearOBK(0); @@ -260,6 +290,7 @@ void Test_Expressions_RunTests_Basic() { //SELFTEST_ASSERT_EXPRESSION("15.0+$CH18+1000\n\r", 30.0f + 1000); //SELFTEST_ASSERT_EXPRESSION("15.0/$CH18+1000\n\r", 1.0f + 1000); //SELFTEST_ASSERT_EXPRESSION("1.50/$CH18+1000\n\r", 0.1f + 1000); + } #endif diff --git a/src/win_main.c b/src/win_main.c index d4925ba78..c064ddcb0 100644 --- a/src/win_main.c +++ b/src/win_main.c @@ -132,6 +132,10 @@ void SIM_ClearOBK(const char *flashPath) { Main_Init(); } void Win_DoUnitTests() { + + + Test_Expressions_RunTests_Braces(); + Test_Expressions_RunTests_Basic(); //Test_Enums(); Test_Backlog(); Test_DoorSensor(); @@ -183,7 +187,6 @@ void Win_DoUnitTests() { Test_ButtonEvents(); Test_Commands_Alias(); Test_Demo_SignAndValue(); - Test_Expressions_RunTests_Basic(); Test_LEDDriver(); Test_LFS(); Test_Scripting(); From c584ed0c8993206b1cf75433968d1d87f6ead2ff Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 18:09:37 +0200 Subject: [PATCH 2/9] better braces support --- src/cmnds/cmd_if.c | 2 +- src/selftest/selftest_expressions.c | 79 ++++++++++++++++++----------- src/selftest/selftest_local.h | 2 + 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/cmnds/cmd_if.c b/src/cmnds/cmd_if.c index 05db0f18b..c92a55dd5 100644 --- a/src/cmnds/cmd_if.c +++ b/src/cmnds/cmd_if.c @@ -820,7 +820,7 @@ float CMD_EvaluateExpression(const char *s, const char *stop) { return 0; } } - if (*s == '(' && stop[-1] == ')' && CMD_FindMatchingBrace(s) == (stop-1)) { + while (*s == '(' && stop[-1] == ')' && CMD_FindMatchingBrace(s) == (stop-1)) { s++; stop--; } diff --git a/src/selftest/selftest_expressions.c b/src/selftest/selftest_expressions.c index 86d2fcd47..576462e3b 100644 --- a/src/selftest/selftest_expressions.c +++ b/src/selftest/selftest_expressions.c @@ -2,36 +2,6 @@ #include "selftest_local.h" -void Test_Expressions_RunTests_Braces() { - SELFTEST_ASSERT_EXPRESSION("2*(3+3)", 12); - SELFTEST_ASSERT_EXPRESSION("2*(3+7)", 20); - SELFTEST_ASSERT_EXPRESSION("2*(3+4)", 14); - SELFTEST_ASSERT_EXPRESSION("4*(3+4)", 28); - SELFTEST_ASSERT_EXPRESSION("4*(3+4+3)", 40); - SELFTEST_ASSERT_EXPRESSION("9*(2+6+1)", 81); - SELFTEST_ASSERT_EXPRESSION("2*(8+7)", 30); - SELFTEST_ASSERT_EXPRESSION("10*(3+5)", 80); - SELFTEST_ASSERT_EXPRESSION("3*(7+7)", 42); - SELFTEST_ASSERT_EXPRESSION("11*(2+3)", 55); - SELFTEST_ASSERT_EXPRESSION("12*(3+3+3)", 108); - SELFTEST_ASSERT_EXPRESSION("5*(4+5)", 45); - SELFTEST_ASSERT_EXPRESSION("2*((3+5)*2)", 32); - SELFTEST_ASSERT_EXPRESSION("4*(3+(2*5))", 52); - SELFTEST_ASSERT_EXPRESSION("(3*(2+3))*(4+1)", 75); - SELFTEST_ASSERT_EXPRESSION("(2+3)*(4+(5*2))", 70); - SELFTEST_ASSERT_EXPRESSION("((3+2)*(2+1))*2", 30); - SELFTEST_ASSERT_EXPRESSION("4*((2+5)+(3*2))", 52); - SELFTEST_ASSERT_EXPRESSION("2*(3+((4*2)+1))", 24); - SELFTEST_ASSERT_EXPRESSION("((3+4)*(2+2))*2", 56); - SELFTEST_ASSERT_EXPRESSION("(5*(3+(2*2)))+10", 45); - SELFTEST_ASSERT_EXPRESSION("(6+4)*(3+(2*3))", 90); - SELFTEST_ASSERT_EXPRESSION("2*(3+5)+((2+3)*4)", 36); - SELFTEST_ASSERT_EXPRESSION("((4*2)+(3*(2+3)))*2", 46); - SELFTEST_ASSERT_EXPRESSION("((3+4)*(5+6))+((2*3)+4)", 87); - - - -} void Test_Expressions_RunTests_Basic() { // reset whole device SIM_ClearOBK(0); @@ -286,6 +256,13 @@ void Test_Expressions_RunTests_Basic() { SELFTEST_ASSERT((3 - 6 % 4 + 2) == 3); SELFTEST_ASSERT_EXPRESSION("3 - 6 % 4 + 2", 3) + // try with braces + SELFTEST_ASSERT(((3 - 6) % 4 + 2) == -1); + SELFTEST_ASSERT_EXPRESSION("(3 - 6) % 4 + 2", -1) + + SELFTEST_ASSERT(((3 - 6) % (4 + 2)) == -3); + SELFTEST_ASSERT_EXPRESSION("(3 - 6) % (4 + 2)", -3) + //CHANNEL_Set(18, 15, 0); //SELFTEST_ASSERT_EXPRESSION("15.0+$CH18+1000\n\r", 30.0f + 1000); //SELFTEST_ASSERT_EXPRESSION("15.0/$CH18+1000\n\r", 1.0f + 1000); @@ -293,4 +270,46 @@ void Test_Expressions_RunTests_Basic() { } + + +void Test_Expressions_RunTests_Braces() { + SELFTEST_ASSERT_EXPRESSION("2*(3+3)", 12); + SELFTEST_ASSERT_EXPRESSION("2*((3+3))", 12); + SELFTEST_ASSERT_EXPRESSION("(2*((3+3)))", 12); + SELFTEST_ASSERT_EXPRESSION("((2)*((3+3)))", 12); + SELFTEST_ASSERT_EXPRESSION("(((2)*((3+3))))", 12); + SELFTEST_ASSERT_EXPRESSION("(((2)*(((3)+(3)))))", 12); + SELFTEST_ASSERT_EXPRESSION("2*(3+7)", 20); + SELFTEST_ASSERT_EXPRESSION("2*(3+4)", 14); + SELFTEST_ASSERT_EXPRESSION("4*(3+4)", 28); + SELFTEST_ASSERT_EXPRESSION("4*(3+4+3)", 40); + SELFTEST_ASSERT_EXPRESSION("9*(2+6+1)", 81); + SELFTEST_ASSERT_EXPRESSION("2*(8+7)", 30); + SELFTEST_ASSERT_EXPRESSION("10*(3+5)", 80); + SELFTEST_ASSERT_EXPRESSION("3*(7+7)", 42); + SELFTEST_ASSERT_EXPRESSION("11*(2+3)", 55); + SELFTEST_ASSERT_EXPRESSION("12*(3+3+3)", 108); + SELFTEST_ASSERT_EXPRESSION("5*(4+5)", 45); + SELFTEST_ASSERT_EXPRESSION("2*((3+5)*2)", 32); + SELFTEST_ASSERT_EXPRESSION("4*(3+(2*5))", 52); + SELFTEST_ASSERT_EXPRESSION("(3*(2+3))*(4+1)", 75); + SELFTEST_ASSERT_EXPRESSION("(2+3)*(4+(5*2))", 70); + SELFTEST_ASSERT_EXPRESSION("((3+2)*(2+1))*2", 30); + SELFTEST_ASSERT_EXPRESSION("4*((2+5)+(3*2))", 52); + SELFTEST_ASSERT_EXPRESSION("2*(3+((4*2)+1))", 24); + SELFTEST_ASSERT_EXPRESSION("((3+4)*(2+2))*2", 56); + SELFTEST_ASSERT_EXPRESSION("(5*(3+(2*2)))+10", 45); + SELFTEST_ASSERT_EXPRESSION("(6+4)*(3+(2*3))", 90); + SELFTEST_ASSERT_EXPRESSION("2*(3+5)+((2+3)*4)", 36); + SELFTEST_ASSERT_EXPRESSION("((4*2)+(3*(2+3)))*2", 46); + SELFTEST_ASSERT_EXPRESSION("((3+4)*(5+6))+((2*3)+4)", 87); + CMD_ExecuteCommand("setChannel 1 4",0); + SELFTEST_ASSERT_EXPRESSION("((3+$CH1)*(5+6))+((2.0*3.0)+$CH1)", 87); + CMD_ExecuteCommand("setChannel 2 3", 0); + SELFTEST_ASSERT_EXPRESSION("(($CH2+$CH1)*(5+6))+((2.0*$CH2)+$CH1)", 87); + + + +} + #endif diff --git a/src/selftest/selftest_local.h b/src/selftest/selftest_local.h index aac314e33..1617651f9 100644 --- a/src/selftest/selftest_local.h +++ b/src/selftest/selftest_local.h @@ -138,6 +138,8 @@ void Test_ChargeLimitDriver(); void Test_WS2812B(); void Test_DoorSensor(); void Test_Enums(); +void Test_Expressions_RunTests_Basic(); +void Test_Expressions_RunTests_Braces(); void Test_GetJSONValue_Setup(const char *text); void Test_FakeHTTPClientPacket_GET(const char *tg); From d8ccf4e9b1925cc3b1677f8f3a3379ae0c4f1e42 Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 19:27:40 +0200 Subject: [PATCH 3/9] Simulator: DHT object, read temperature/humidity from DH11 object --- openBeken_win32_mvsc2017.vcxproj | 2 + openBeken_win32_mvsc2017.vcxproj.filters | 2 + src/driver/drv_dht_internal.c | 13 +++--- src/sim/Controller_DHT11.cpp | 51 ++++++++++++++++++++++++ src/sim/Controller_DHT11.h | 41 +++++++++++++++++++ src/sim/PrefabManager.cpp | 33 +++++++++++++++ src/sim/PrefabManager.h | 1 + src/sim/Simulation.h | 10 +++++ src/sim/sim_local.h | 1 + src/sim/sim_sdl.cpp | 10 ++--- 10 files changed, 151 insertions(+), 13 deletions(-) create mode 100644 src/sim/Controller_DHT11.cpp create mode 100644 src/sim/Controller_DHT11.h diff --git a/openBeken_win32_mvsc2017.vcxproj b/openBeken_win32_mvsc2017.vcxproj index 27a9d5155..1401e0055 100644 --- a/openBeken_win32_mvsc2017.vcxproj +++ b/openBeken_win32_mvsc2017.vcxproj @@ -759,6 +759,7 @@ + @@ -1074,6 +1075,7 @@ + diff --git a/openBeken_win32_mvsc2017.vcxproj.filters b/openBeken_win32_mvsc2017.vcxproj.filters index 503c858a0..fba5ff623 100644 --- a/openBeken_win32_mvsc2017.vcxproj.filters +++ b/openBeken_win32_mvsc2017.vcxproj.filters @@ -341,6 +341,7 @@ + @@ -495,6 +496,7 @@ + diff --git a/src/driver/drv_dht_internal.c b/src/driver/drv_dht_internal.c index c5631d58c..1e7a28fc1 100644 --- a/src/driver/drv_dht_internal.c +++ b/src/driver/drv_dht_internal.c @@ -276,7 +276,7 @@ float DHT_computeHeatIndexInternal(dht_t *dht, float temperature, float percentH * @param force * true if using force mode * @return float value - */ + */ bool DHT_read(dht_t *dht, bool force) { byte *data = dht->data; // Check if sensor was read less than two seconds ago and return early @@ -288,14 +288,11 @@ bool DHT_read(dht_t *dht, bool force) { dht->_lastreadtime = currenttime; #if WINDOWS + bool SIM_ReadDHT11(int pin, byte *data); + dht->_lastresult = true; - data[0] = data[1] = data[2] = data[3] = data[4] = 0; - // temp 19 - data[2] = 19; - // humidity 67.8 - data[0] = 67; - data[1] = 0; - return true; + + return SIM_ReadDHT11(dht->_pin, data); #endif // Reset 40 bits of received data to zero. data[0] = data[1] = data[2] = data[3] = data[4] = 0; diff --git a/src/sim/Controller_DHT11.cpp b/src/sim/Controller_DHT11.cpp new file mode 100644 index 000000000..8f129cd63 --- /dev/null +++ b/src/sim/Controller_DHT11.cpp @@ -0,0 +1,51 @@ +#ifdef WINDOWS +#include "Simulator.h" +#include "Simulation.h" +#include "sim_local.h" +#include "Controller_DHT11.h" +#include "Shape.h" +#include "Junction.h" +#include "Text.h" + +extern "C" bool SIM_ReadDHT11(int pin, byte *data) { + CSimulation *s = g_sim->getSim(); + data[0] = data[1] = data[2] = data[3] = data[4] = 0; + // temp 19 + data[2] = 19; + // humidity 67 + data[0] = 67; + data[1] = 0; + if (s == 0) + return true; + CControllerDHT11 *dht = s->findFirstControllerOfType(); + if (dht == 0) + return true; + data[2] = dht->getTemperature(); + data[0] = dht->getHumidity(); + + return true; +} + +void CControllerDHT11::onDrawn() { + if (txt_temperature->isBeingEdited() == false) { + realTemperature = txt_temperature->getFloat(); + } + if (txt_humidity->isBeingEdited() == false) { + realHumidity = txt_humidity->getFloat(); + } +} +class CControllerBase *CControllerDHT11::cloneController(class CShape *origOwner, class CShape *newOwner) { + CControllerDHT11 *r = new CControllerDHT11(); + if (dat) { + r->dat = newOwner->findShapeByName_r(dat->getName())->asJunction(); + } + if (txt_temperature) { + r->txt_temperature = newOwner->findShapeByName_r(txt_temperature->getName())->asText(); + } + if (txt_humidity) { + r->txt_humidity = newOwner->findShapeByName_r(txt_humidity->getName())->asText(); + } + return r; +} + +#endif diff --git a/src/sim/Controller_DHT11.h b/src/sim/Controller_DHT11.h new file mode 100644 index 000000000..5da1a19e7 --- /dev/null +++ b/src/sim/Controller_DHT11.h @@ -0,0 +1,41 @@ +#ifndef __CONTROLLER_DHT11_H__ +#define __CONTROLLER_DHT11_H__ + +#include "sim_local.h" +#include "Controller_Base.h" +#include "Coord.h" + +class CControllerDHT11 : public CControllerBase { + class CJunction *dat; + class CText *txt_temperature, *txt_humidity; + + void setShapesActive(bool b); + void setShapesFillColor(const CColor &c); + float realTemperature; + float realHumidity; +public: + CControllerDHT11() { + dat = 0; + txt_temperature = txt_humidity = 0; + realTemperature = 19.8f; + realHumidity = 68.0f; + } + CControllerDHT11(class CJunction *_dat, CText *_txt_temperature, CText *_txt_humidity) { + dat = _dat; + txt_temperature = _txt_temperature; + txt_humidity = _txt_humidity; + realTemperature = 19.8f; + realHumidity = 68.0f; + } + virtual void onDrawn(); + virtual class CControllerBase *cloneController(class CShape *origOwner, class CShape *newOwner); + + float getTemperature() const { + return realTemperature; + } + float getHumidity() const { + return realHumidity; + } +}; + +#endif // __CONTROLLER_DHT11_H__ diff --git a/src/sim/PrefabManager.cpp b/src/sim/PrefabManager.cpp index 561a93e04..cd1ba705a 100644 --- a/src/sim/PrefabManager.cpp +++ b/src/sim/PrefabManager.cpp @@ -10,6 +10,7 @@ #include "Controller_BL0942.h" #include "Controller_Pot.h" #include "Controller_WS2812.h" +#include "Controller_DHT11.h" #include "Junction.h" class CShape *PrefabManager::generateVDD() { @@ -117,6 +118,37 @@ class CShape *PrefabManager::generateBL0942() { o->setController(cntr); return o; } +class CShape *PrefabManager::generateDHT11() { + + CShape *o = new CShape(); + o->setName("DHT11"); + int w = 40; + int h = 40; + o->addText(-w - 5, -h - 5, "DHT11"); + o->addText(-w + 5, -h + 15, "T:"); + o->addText(-w + 5, -h + 35, "H:"); + CText *tx_temperatura = o->addText(-w + 25, -h + 15, "19.9C", true, false)->asText(); + tx_temperatura->setName("tex_temperature"); + CText *tx_humidity = o->addText(-w + 25, -h + 35, "85%", true, false)->asText(); + tx_humidity->setName("text_humidity"); + o->addRect(-w, -h, w * 2, 80); + CJunction *dat = o->addJunction(w + 20, 0, "DAT"); + o->addLine(w + 20, 0, w, 0); + dat->setName("DAT"); + dat->addText(-5, -5, "DAT"); + + CJunction *vdd = o->addJunction(w + 20, 20, "VDD"); + o->addLine(w + 20, 20, w, 20); + vdd->setName("VDD"); + vdd->addText(-5, -5, "VDD"); + CJunction *gnd = o->addJunction(w + 20, -20, "GND"); + o->addLine(w + 20, -20, w, -20); + gnd->setName("GND"); + gnd->addText(-5, -5, "GND"); + CControllerDHT11 *cntr = new CControllerDHT11(dat, tx_temperatura, tx_humidity); + o->setController(cntr); + return o; +} class CShape *PrefabManager::generateTest() { CShape *o = new CShape(); @@ -510,6 +542,7 @@ void PrefabManager::createDefaultPrefabs() { addPrefab(generateBL0942()); addPrefab(generatePot()); addPrefab(generateWS2812B()); + addPrefab(generateDHT11()); } diff --git a/src/sim/PrefabManager.h b/src/sim/PrefabManager.h index 226f85e38..222954c0c 100644 --- a/src/sim/PrefabManager.h +++ b/src/sim/PrefabManager.h @@ -24,6 +24,7 @@ class PrefabManager { class CShape *generateVDD(); class CShape *generatePot(); class CShape *generateWS2812B(); + class CShape *generateDHT11(); public: PrefabManager(CSimulator *ps) { sim = ps; diff --git a/src/sim/Simulation.h b/src/sim/Simulation.h index 2c31fd124..c27b864f1 100644 --- a/src/sim/Simulation.h +++ b/src/sim/Simulation.h @@ -21,6 +21,16 @@ class CSimulation { void registerJunctions(class CShape *s); class CShape *findDeepText_r(const class Coord &p, class CShape *cur); public: + template + T *findFirstControllerOfType() { + for (int i = 0; i < objects.size(); i++) { + CControllerBase *c = objects[i]->getController(); + T *r = dynamic_cast(c); + if (r) + return r; + } + return 0; + } void setSimulator(class CSimulator *ssim) { this->sim = ssim; } diff --git a/src/sim/sim_local.h b/src/sim/sim_local.h index e34e06103..c62301070 100644 --- a/src/sim/sim_local.h +++ b/src/sim/sim_local.h @@ -45,6 +45,7 @@ bool FS_Exists(const char *fname); extern int WinWidth; extern int WinHeight; extern int gridSize; +extern class CSimulator *g_sim; extern "C" { void CMD_ExpandConstantsWithinString(const char *in, char *out, int outLen); diff --git a/src/sim/sim_sdl.cpp b/src/sim/sim_sdl.cpp index d9592fde0..9289d6d07 100644 --- a/src/sim/sim_sdl.cpp +++ b/src/sim/sim_sdl.cpp @@ -172,16 +172,16 @@ bool FS_WriteTextFile(const char *data, const char *fname) { fclose(f); return false; } -CSimulator *sim; +CSimulator *g_sim; extern "C" int SIM_CreateWindow(int argc, char **argv) { glutInit(&argc, argv); - sim = new CSimulator(); - sim->createWindow(); - sim->loadRecentProject(); + g_sim = new CSimulator(); + g_sim->createWindow(); + g_sim->loadRecentProject(); return 0; } extern "C" void SIM_RunWindow() { - sim->drawWindow(); + g_sim->drawWindow(); } #endif From c79e356ba2e9c750355553828b78b6cd96cf930e Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 21:56:22 +0200 Subject: [PATCH 4/9] simulator: support multiple DHTs11 --- src/sim/Controller_DHT11.cpp | 24 ++++++++++++++++------ src/sim/Controller_DHT11.h | 3 +++ src/sim/Controller_SimulatorLink.cpp | 7 +++++++ src/sim/Controller_SimulatorLink.h | 3 ++- src/sim/Simulation.h | 12 +++++++++++ src/sim/Simulator.h | 3 +++ src/sim/Solver.cpp | 30 ++++++++++++++++++++++++++++ src/sim/Solver.h | 1 + src/sim/sim_local.h | 8 ++++++++ 9 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/sim/Controller_DHT11.cpp b/src/sim/Controller_DHT11.cpp index 8f129cd63..d876ef722 100644 --- a/src/sim/Controller_DHT11.cpp +++ b/src/sim/Controller_DHT11.cpp @@ -1,8 +1,11 @@ #ifdef WINDOWS #include "Simulator.h" #include "Simulation.h" +#include "Junction.h" +#include "Solver.h" #include "sim_local.h" #include "Controller_DHT11.h" +#include "Controller_SimulatorLink.h" #include "Shape.h" #include "Junction.h" #include "Text.h" @@ -17,12 +20,21 @@ extern "C" bool SIM_ReadDHT11(int pin, byte *data) { data[1] = 0; if (s == 0) return true; - CControllerDHT11 *dht = s->findFirstControllerOfType(); - if (dht == 0) - return true; - data[2] = dht->getTemperature(); - data[0] = dht->getHumidity(); - + TArray dhts = s->findControllersOfType(); + for (int d = 0; d < dhts.size(); d++) { + CControllerDHT11 *dht = dhts[d]; + CControllerSimulatorLink *wifi = s->findFirstControllerOfType(); + if (wifi == 0) + return true; + CJunction *p = wifi->findJunctionByGPIOIndex(pin); + if (p == 0) + return true; + data[2] = dht->getTemperature(); + data[0] = dht->getHumidity(); + if (g_sim->getSolver()->hasPath(dht->getDataPin(), p)) { + return true; + } + } return true; } diff --git a/src/sim/Controller_DHT11.h b/src/sim/Controller_DHT11.h index 5da1a19e7..74db98157 100644 --- a/src/sim/Controller_DHT11.h +++ b/src/sim/Controller_DHT11.h @@ -36,6 +36,9 @@ class CControllerDHT11 : public CControllerBase { float getHumidity() const { return realHumidity; } + class CJunction *getDataPin() { + return dat; + } }; #endif // __CONTROLLER_DHT11_H__ diff --git a/src/sim/Controller_SimulatorLink.cpp b/src/sim/Controller_SimulatorLink.cpp index 19425a11b..20c70118b 100644 --- a/src/sim/Controller_SimulatorLink.cpp +++ b/src/sim/Controller_SimulatorLink.cpp @@ -7,6 +7,13 @@ CControllerSimulatorLink::CControllerSimulatorLink() { +} +CJunction *CControllerSimulatorLink::findJunctionByGPIOIndex(int idx) { + for (int i = 0; i < related.size(); i++) { + if (related[i]->getGPIO() == idx) + return related[i]; + } + return 0; } class CControllerBase *CControllerSimulatorLink::cloneController(class CShape *origOwner, class CShape *newOwner) { CControllerSimulatorLink *r = new CControllerSimulatorLink(); diff --git a/src/sim/Controller_SimulatorLink.h b/src/sim/Controller_SimulatorLink.h index a32354244..a4238876b 100644 --- a/src/sim/Controller_SimulatorLink.h +++ b/src/sim/Controller_SimulatorLink.h @@ -15,6 +15,7 @@ class CControllerSimulatorLink : public CControllerBase { virtual void onDrawn(); class CControllerBase *cloneController(class CShape *origOwner, class CShape *newOwner); + CJunction *findJunctionByGPIOIndex(int idx); }; -#endif // __CONTROLLER_BUTTON_H__ +#endif // __CONTROLLER_SIMULATORLINK_H__ diff --git a/src/sim/Simulation.h b/src/sim/Simulation.h index c27b864f1..9f4de5e5d 100644 --- a/src/sim/Simulation.h +++ b/src/sim/Simulation.h @@ -31,6 +31,18 @@ class CSimulation { } return 0; } + template + TArray findControllersOfType() { + TArray ret; + for (int i = 0; i < objects.size(); i++) { + CControllerBase *c = objects[i]->getController(); + T *r = dynamic_cast(c); + if (r) { + ret.push_back(r); + } + } + return ret; + } void setSimulator(class CSimulator *ssim) { this->sim = ssim; } diff --git a/src/sim/Simulator.h b/src/sim/Simulator.h index b0f9ef142..0072862b7 100644 --- a/src/sim/Simulator.h +++ b/src/sim/Simulator.h @@ -47,6 +47,9 @@ class CSimulator { class CursorManager*getCursorMgr() { return cur; } + class CSolver *getSolver() { + return solver; + } class CShape *allocByClassName(const char *className); bool isMouseButtonHold(int idx) const { return bMouseButtonStates[idx]; diff --git a/src/sim/Solver.cpp b/src/sim/Solver.cpp index 43995b52b..215c9190a 100644 --- a/src/sim/Solver.cpp +++ b/src/sim/Solver.cpp @@ -26,6 +26,36 @@ void CSolver::solveVoltages() { } } } +bool CSolver::hasPath(class CJunction *a, class CJunction *b) { + TArray toVisit; + TArray checked; + toVisit.push_back(a); + while (toVisit.size()) { + CJunction *j = toVisit.pop(); + checked.push_back(j); + for (int i = 0; i < j->getEdgesCount(); i++) { + CJunction *other = j->getEdge(i)->getOther(j); + if (other == 0) + continue; + if (checked.contains(other)) + continue; + if (other == b) + return true; + toVisit.push_back(other); + } + for (int i = 0; i < j->getLinksCount(); i++) { + CJunction *other = j->getLink(i); + if (other == 0) + continue; + if (checked.contains(other)) + continue; + if (other == b) + return true; + toVisit.push_back(other); + } + } + return false; +} // Idea: count steps to VDD/GND and use it to support multiple objects on line? void CSolver::floodJunctions(CJunction *ju, float voltage, float duty, int depth) { if (ju == 0) diff --git a/src/sim/Solver.h b/src/sim/Solver.h index cfac8eea3..d88408af9 100644 --- a/src/sim/Solver.h +++ b/src/sim/Solver.h @@ -12,6 +12,7 @@ class CSolver { sim = p; } void solveVoltages(); + bool hasPath(class CJunction *a, class CJunction *b); }; #endif \ No newline at end of file diff --git a/src/sim/sim_local.h b/src/sim/sim_local.h index c62301070..4a8525d88 100644 --- a/src/sim/sim_local.h +++ b/src/sim/sim_local.h @@ -57,6 +57,14 @@ extern "C" { template class TArray : public std::vector { public: + T pop() { + if (!this->empty()) { + T lastElement = this->back(); + this->pop_back(); + return lastElement; + } + return 0; + } void remove(T o) { this->erase(std::remove(this->begin(), this->end(), o), this->end()); } From a951dd220b068088ca3a872f78f81c1ed2bc4661 Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 22:06:08 +0200 Subject: [PATCH 5/9] selftest crash fix --- src/sim/Controller_DHT11.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sim/Controller_DHT11.cpp b/src/sim/Controller_DHT11.cpp index d876ef722..4e060511a 100644 --- a/src/sim/Controller_DHT11.cpp +++ b/src/sim/Controller_DHT11.cpp @@ -11,13 +11,15 @@ #include "Text.h" extern "C" bool SIM_ReadDHT11(int pin, byte *data) { - CSimulation *s = g_sim->getSim(); data[0] = data[1] = data[2] = data[3] = data[4] = 0; // temp 19 data[2] = 19; // humidity 67 data[0] = 67; data[1] = 0; + if (g_sim == 0) + return true; + CSimulation *s = g_sim->getSim(); if (s == 0) return true; TArray dhts = s->findControllersOfType(); From b0f7fdaa0bc7604876cad8ace6ebfff30196555b Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 22:13:23 +0200 Subject: [PATCH 6/9] silence same handler redefinition spam --- src/cmnds/cmd_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cmnds/cmd_main.c b/src/cmnds/cmd_main.c index 5e5f1b04e..0e7879d3b 100644 --- a/src/cmnds/cmd_main.c +++ b/src/cmnds/cmd_main.c @@ -844,7 +844,10 @@ void CMD_RegisterCommand(const char* name, commandHandler_t handler, void* conte // check newCmd = CMD_Find(name); if (newCmd != 0) { - ADDLOG_ERROR(LOG_FEATURE_CMD, "command with name %s already exists!", name); + // it happens very often in Simulator due to the lack of the ability to remove commands + if (newCmd->handler != handler) { + ADDLOG_ERROR(LOG_FEATURE_CMD, "command with name %s already exists!", name); + } return; } ADDLOG_DEBUG(LOG_FEATURE_CMD, "Adding command %s", name); From afba4928ce9973c6beb47a45b5a2f978865e4adb Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 22:13:32 +0200 Subject: [PATCH 7/9] silence channel get --- src/mqtt/new_mqtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt/new_mqtt.c b/src/mqtt/new_mqtt.c index 2864f6a8d..b36a302dd 100644 --- a/src/mqtt/new_mqtt.c +++ b/src/mqtt/new_mqtt.c @@ -585,7 +585,7 @@ int channelGet(obk_mqtt_request_t* request) { // atoi won't parse any non-decimal chars, so it should skip over the rest of the topic. channel = atoi(p); - addLogAdv(LOG_INFO, LOG_FEATURE_MQTT, "channelGet channel %i", channel); + //addLogAdv(LOG_INFO, LOG_FEATURE_MQTT, "channelGet channel %i", channel); // if channel out of range, stop here. if ((channel < 0) || (channel > 32)) { From 239eb39fe7a5a59117684d3a92eb4ea47313c694 Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Sun, 22 Sep 2024 22:50:49 +0200 Subject: [PATCH 8/9] silence dht --- src/driver/drv_dht.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/driver/drv_dht.c b/src/driver/drv_dht.c index b0d4f9950..e4aa5afe0 100644 --- a/src/driver/drv_dht.c +++ b/src/driver/drv_dht.c @@ -101,8 +101,8 @@ void DHT_OnEverySecond() { if (g_dhts[i]->_lastresult != 0) { // don't want to loose accuracy, so multiply by 10 // We have a channel types to handle that - CHANNEL_Set(g_cfg.pins.channels[i], (int)(temp * 10), 0); - CHANNEL_Set(g_cfg.pins.channels2[i], (int)(humid), 0); + CHANNEL_Set(g_cfg.pins.channels[i], (int)(temp * 10), CHANNEL_SET_FLAG_SILENT); + CHANNEL_Set(g_cfg.pins.channels2[i], (int)(humid), CHANNEL_SET_FLAG_SILENT); } } } From 266954ac307cde6688701d141c11b5c7369072a4 Mon Sep 17 00:00:00 2001 From: Tester <85486843+openshwprojects@users.noreply.github.com> Date: Mon, 23 Sep 2024 08:35:34 +0200 Subject: [PATCH 9/9] remove old test code --- src/driver/drv_dht.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/driver/drv_dht.c b/src/driver/drv_dht.c index e4aa5afe0..3591d603d 100644 --- a/src/driver/drv_dht.c +++ b/src/driver/drv_dht.c @@ -10,25 +10,9 @@ #include "drv_local.h" #include "drv_dht_internal.h" -// test device -static dht_t *test = 0; // per-pin devices static dht_t **g_dhts = 0; -// simplest demo -void DHT_DoMyDHTTest() { - if (test == 0) { - test = DHT_Create(24, DHT11); - } - if (test) { - float temp, humid; - - humid = DHT_readHumidity(test, false); - temp = DHT_readTemperature(test, false, false); - - addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "DHT says %f %f", humid, temp); - } -} int translateDHTType(int role) { if (role == IOR_DHT11) return DHT11;