diff --git a/openBeken_win32_mvsc2017.vcxproj b/openBeken_win32_mvsc2017.vcxproj index 6fc07d063..db16fc558 100644 --- a/openBeken_win32_mvsc2017.vcxproj +++ b/openBeken_win32_mvsc2017.vcxproj @@ -324,6 +324,9 @@ true + + true + true true @@ -515,6 +518,7 @@ + diff --git a/openBeken_win32_mvsc2017.vcxproj.filters b/openBeken_win32_mvsc2017.vcxproj.filters index 6dce37eb1..75711587e 100644 --- a/openBeken_win32_mvsc2017.vcxproj.filters +++ b/openBeken_win32_mvsc2017.vcxproj.filters @@ -411,6 +411,12 @@ Simulator + + SelfTest + + + HAL + diff --git a/src/cmnds/cmd_if.c b/src/cmnds/cmd_if.c index c3aa4a323..30ce4cab6 100644 --- a/src/cmnds/cmd_if.c +++ b/src/cmnds/cmd_if.c @@ -116,15 +116,16 @@ const char *strCompareBound(const char *s, const char *templ, const char *stoppe } else { - return 0; - } - } else { - char c1 = tolower((unsigned char)*s); - char c2 = tolower((unsigned char)*templ); - if(c1 != c2) { - return 0; + return 0; } } + else { + char c1 = tolower((unsigned char)*s); + char c2 = tolower((unsigned char)*templ); + if (c1 != c2) { + return 0; + } + } s++; templ++; } @@ -144,7 +145,7 @@ const char *CMD_ExpandConstant(const char *s, const char *stop, float *out) { const char *ret; ret = strCompareBound(s, "MQTTOn", stop, false); - if(ret) { + if (ret) { ADDLOG_EXTRADEBUG(LOG_FEATURE_EVENT, "CMD_ExpandConstant: MQTTOn"); *out = Main_HasMQTTConnected(); return ret; @@ -164,19 +165,19 @@ const char *CMD_ExpandConstant(const char *s, const char *stop, float *out) { return ret; } ret = strCompareBound(s, "$led_dimmer", stop, 0); - if(ret) { + if (ret) { ADDLOG_EXTRADEBUG(LOG_FEATURE_EVENT, "CMD_ExpandConstant: led_dimmer"); *out = LED_GetDimmer(); return ret; } ret = strCompareBound(s, "$led_enableAll", stop, 0); - if(ret) { + if (ret) { ADDLOG_EXTRADEBUG(LOG_FEATURE_EVENT, "CMD_ExpandConstant: led_enableAll"); *out = LED_GetEnableAll(); return ret; } ret = strCompareBound(s, "$led_hue", stop, 0); - if(ret) { + if (ret) { ADDLOG_EXTRADEBUG(LOG_FEATURE_EVENT, "CMD_ExpandConstant: led_hue"); *out = LED_GetHue(); return ret; @@ -200,13 +201,13 @@ const char *CMD_ExpandConstant(const char *s, const char *stop, float *out) { return ret; } ret = strCompareBound(s, "$led_saturation", stop, 0); - if(ret) { + if (ret) { ADDLOG_EXTRADEBUG(LOG_FEATURE_EVENT, "CMD_ExpandConstant: led_saturation"); *out = LED_GetSaturation(); return ret; } ret = strCompareBound(s, "$led_temperature", stop, 0); - if(ret) { + if (ret) { ADDLOG_EXTRADEBUG(LOG_FEATURE_EVENT, "CMD_ExpandConstant: led_temperature"); *out = LED_GetTemperature(); return ret; @@ -215,6 +216,36 @@ const char *CMD_ExpandConstant(const char *s, const char *stop, float *out) { return false; } #if WINDOWS + +void SIM_GenerateChannelStatesDesc(char *o, int outLen) { + int role; + const char *roleStr; + char buffer[64]; + for (int i = 0; i < CHANNEL_MAX; i++) { + bool bFound = false; + for (int j = 0; j < PLATFORM_GPIO_MAX; j++) { + if (g_cfg.pins.roles[j] == IOR_None) + continue; + if (g_cfg.pins.channels[j] != i) + continue; + if (bFound == false) { + bFound = true; + snprintf(buffer, sizeof(buffer), "Ch %i - value %i - ",i,CHANNEL_Get(i)); + strcat_safe(o, buffer, outLen); + } + else { + strcat_safe(o, ", ", outLen); + } + role = g_cfg.pins.roles[j]; + roleStr = PIN_RoleToString(role); + strcat_safe(o, roleStr, outLen); + } + if (bFound) { + strcat_safe(o, "\n", outLen); + } + } +} + const char *CMD_ExpandConstantString(const char *s, const char *stop, char *out, int outLen) { int idx; const char *ret; @@ -233,6 +264,11 @@ const char *CMD_ExpandConstantString(const char *s, const char *stop, char *out, SIM_GeneratePinStatesDesc(out, outLen); return ret; } + ret = strCompareBound(s, "$channelstates", stop, false); + if (ret) { + SIM_GenerateChannelStatesDesc(out, outLen); + return ret; + } return false; } #endif diff --git a/src/debug_tuyaMCUsimulator.c b/src/debug_tuyaMCUsimulator.c index f11375837..6452985a7 100644 --- a/src/debug_tuyaMCUsimulator.c +++ b/src/debug_tuyaMCUsimulator.c @@ -7,8 +7,13 @@ const char *dataToSimulate[] = // dummy entry in order to avoid problems with empty table "", #if 1 - "55AA03070014060000080916000099000023010200040000000310" - + "55AA00050005010400010110", + "55AA0005000501040001000F" +#elif 0 + "55AA03070014060000080916000099000023010200040000000310", + "55AA0307000C03000008160C160C0000000367", + "55AA0307000C040000080C010C01000000033E", + "55AA030700140600000809350000F800003A010200040000002FD1" #elif 0 "55AA030000010003", "55AA0301002A7B2270223A226C696834766A656F79616F346A656B75222C2276223A22322E302E30222C226D223A307D41", @@ -58,7 +63,7 @@ int delay_between_packets = 20; int max_bytes_per_frame = 200; int curString = 0; const char *curP = 0; -int current_delay_to_wait_ms = 1000; +int current_delay_to_wait_ms = 100; void NewTuyaMCUSimulator_RunQuickTick(int deltaMS) { byte b; @@ -75,6 +80,16 @@ void NewTuyaMCUSimulator_RunQuickTick(int deltaMS) { curP = dataToSimulate[curString]; } +#if 1 + +#elif 0 + if (DRV_IsRunning("TuyaMCU") == 0) { + CMD_ExecuteCommand("startDriver TuyaMCU", 0); + CMD_ExecuteCommand("startDriver tmSensor ", 0); + CMD_ExecuteCommand("setChannelType 1 readonly", 0); + CMD_ExecuteCommand("linkTuyaMCUOutputToChannel 1 val 1", 0); + } +#else if (DRV_IsRunning("TuyaMCU") == 0) { CMD_ExecuteCommand("startDriver TuyaMCU", 0); CMD_ExecuteCommand("startDriver NTP", 0); @@ -82,11 +97,19 @@ void NewTuyaMCUSimulator_RunQuickTick(int deltaMS) { CMD_ExecuteCommand("setChannelType 2 Voltage_div10", 0); CMD_ExecuteCommand("setChannelType 3 Power", 0); CMD_ExecuteCommand("setChannelType 4 Current_div1000", 0); + CMD_ExecuteCommand("setChannelType 5 EnergyTotal_kWh_div100", 0); CMD_ExecuteCommand("linkTuyaMCUOutputToChannel 16 bool 1", 0); + CMD_ExecuteCommand("linkTuyaMCUOutputToChannel 1 val 5", 0); // TAC2121C VoltageCurrentPower Packet CMD_ExecuteCommand("linkTuyaMCUOutputToChannel 6 RAW_TAC2121C_VCP", 0); + CMD_ExecuteCommand("linkTuyaMCUOutputToChannel 4 RAW_TAC2121C_Yesterday", 0); + CMD_ExecuteCommand("linkTuyaMCUOutputToChannel 3 RAW_TAC2121C_LastMonth", 0); + } +#endif + // make sure that buffer has free size + if (UART_GetDataSize() != 0) { + return; } - while (*curP != 0) { c_added++; if (c_added >= max_bytes_per_frame) { diff --git a/src/hal/bk7231/hal_adc_bk7231.c b/src/hal/bk7231/hal_adc_bk7231.c index 069aa72ee..480d86772 100644 --- a/src/hal/bk7231/hal_adc_bk7231.c +++ b/src/hal/bk7231/hal_adc_bk7231.c @@ -25,12 +25,12 @@ static int adcToGpio[] = { 12,//GPIO12, // ADC6 13,//GPIO13, // ADC7 }; -//static int c_adcToGpio = sizeof(adcToGpio)/sizeof(adcToGpio[0]); +static int c_adcToGpio = sizeof(adcToGpio)/sizeof(adcToGpio[0]); -static uint8_t gpioToAdc(int gpio) { - uint8_t i; - for ( i = 0; i < sizeof(adcToGpio); i++) { +static int gpioToAdc(int gpio) { + int i; + for ( i = 0; i < c_adcToGpio; i++) { if (adcToGpio[i] == gpio) return i; } diff --git a/src/hal/win32/hal_adc_win32.c b/src/hal/win32/hal_adc_win32.c index c5a0f02fd..ee165ea97 100644 --- a/src/hal/win32/hal_adc_win32.c +++ b/src/hal/win32/hal_adc_win32.c @@ -2,13 +2,6 @@ #include "../hal_adc.h" -void HAL_ADC_Init(int pinNumber) { -} - -int HAL_ADC_Read(int pinNumber) { - // TODO - return 123; -} #endif // WINDOWS diff --git a/src/hal/win32/hal_pins_win32.c b/src/hal/win32/hal_pins_win32.c index 922a4a9ec..b68b64eca 100644 --- a/src/hal/win32/hal_pins_win32.c +++ b/src/hal/win32/hal_pins_win32.c @@ -11,12 +11,52 @@ typedef enum simulatedPinMode_e { SIM_PIN_PWM, SIM_PIN_INPUT_PULLUP, SIM_PIN_INPUT, + SIM_PIN_ADC, } simulatedPinMode_t; int g_simulatedPinStates[PLATFORM_GPIO_MAX]; int g_simulatedPWMs[PLATFORM_GPIO_MAX]; simulatedPinMode_t g_pinModes[PLATFORM_GPIO_MAX]; +int g_simulatedADCValues[PLATFORM_GPIO_MAX]; +void SIM_Hack_ClearSimulatedPinRoles() { + memset(g_simulatedPinStates, 0, sizeof(g_simulatedPinStates)); + memset(g_simulatedPWMs, 0, sizeof(g_simulatedPWMs)); + memset(g_pinModes, 0, sizeof(g_pinModes)); + memset(g_simulatedADCValues, 0, sizeof(g_simulatedADCValues)); +} + +static int adcToGpio[] = { + -1, // ADC0 - VBAT + 4, //GPIO4, // ADC1 + 5, //GPIO5, // ADC2 + 23,//GPIO23, // ADC3 + 2,//GPIO2, // ADC4 + 3,//GPIO3, // ADC5 + 12,//GPIO12, // ADC6 + 13,//GPIO13, // ADC7 +}; +static int c_adcToGpio = sizeof(adcToGpio)/sizeof(adcToGpio[0]); + + +static int gpioToAdc(int gpio) { + int i; + for (i = 0; i < c_adcToGpio; i++) { + if (adcToGpio[i] == gpio) + return i; + } + return -1; +} + +void HAL_ADC_Init(int pinNumber) { + g_pinModes[pinNumber] = SIM_PIN_ADC; +} +int HAL_ADC_Read(int pinNumber) { + int channel = gpioToAdc(pinNumber); + if (channel == -1) + return 0; + return g_simulatedADCValues[pinNumber]; +} void SIM_SetSimulatedPinValue(int pinIndex, bool bHigh) { g_simulatedPinStates[pinIndex] = bHigh; } @@ -35,6 +75,23 @@ bool SIM_IsPinPWM(int index) { return true; return false; } +bool SIM_IsPinADC(int index) { + if (g_pinModes[index] == SIM_PIN_ADC) + return true; + return false; +} +void SIM_SetVoltageOnADCPin(int index, float v) { + if (g_pinModes[index] != SIM_PIN_ADC) + return; + //printf("SIM_SetVoltageOnADCPin: %i has %f\n", index, v); + if (v > 3.3f) + v = 3.3f; + if (v < 0) + v = 0; + float f = v / 3.3f; + int iVal = f * 1024; + g_simulatedADCValues[index] = iVal; +} int SIM_GetPWMValue(int index) { return g_simulatedPWMs[index]; } @@ -58,6 +115,10 @@ void SIM_GeneratePinStatesDesc(char *o, int outLen) { sprintf(tmp, "PWM - %i", g_simulatedPWMs[i]); strcat_safe(o, tmp, outLen); } + else if (mode == SIM_PIN_ADC) { + sprintf(tmp, "ADC - %i", g_simulatedADCValues[i]); + strcat_safe(o, tmp, outLen); + } else if (mode == SIM_PIN_OUTPUT) { sprintf(tmp, "Output - %i", g_simulatedPinStates[i]); strcat_safe(o, tmp, outLen); diff --git a/src/httpserver/new_http.c b/src/httpserver/new_http.c index c2caae1f0..0c5df72cf 100644 --- a/src/httpserver/new_http.c +++ b/src/httpserver/new_http.c @@ -399,6 +399,9 @@ const char* htmlPinRoleNames[] = { "error", }; +const char *PIN_RoleToString(int role) { + return htmlPinRoleNames[role]; +} int PIN_ParsePinRoleName(const char* name) { int i; diff --git a/src/new_pins.h b/src/new_pins.h index 26ac994a5..275a8fea8 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -333,6 +333,7 @@ int h_isChannelRelay(int tg_ch); //int PIN_GetPWMIndexForPinIndex(int pin); int PIN_ParsePinRoleName(const char* name); +const char *PIN_RoleToString(int role); // from new_builtin.c /* diff --git a/src/selftest/selftest_buttonEvents.c b/src/selftest/selftest_buttonEvents.c index 781d5da74..09d5a1788 100644 --- a/src/selftest/selftest_buttonEvents.c +++ b/src/selftest/selftest_buttonEvents.c @@ -4,7 +4,7 @@ void Test_ButtonEvents() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); // by default, we have a pull up resistor - so high level SIM_SetSimulatedPinValue(9, true); diff --git a/src/selftest/selftest_changeHandlers.c b/src/selftest/selftest_changeHandlers.c index c93cfb9b3..2196681ab 100644 --- a/src/selftest/selftest_changeHandlers.c +++ b/src/selftest/selftest_changeHandlers.c @@ -4,7 +4,7 @@ void Test_ChangeHandlers() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); // this will only happens when Channel1 value changes from not equal to 0 to the one equal to 0 CMD_ExecuteCommand("addChangeHandler Channel1 == 0 addChannel 10 1111", 0); diff --git a/src/selftest/selftest_cmd_alias.c b/src/selftest/selftest_cmd_alias.c index 2fba122f5..47eed1d21 100644 --- a/src/selftest/selftest_cmd_alias.c +++ b/src/selftest/selftest_cmd_alias.c @@ -4,7 +4,7 @@ void Test_Commands_Alias() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExecuteCommand("alias test1 addChannel 2 10", 0); SELFTEST_ASSERT_CHANNEL(2, 0); diff --git a/src/selftest/selftest_cmd_channels.c b/src/selftest/selftest_cmd_channels.c index feff6b89a..6f133af1c 100644 --- a/src/selftest/selftest_cmd_channels.c +++ b/src/selftest/selftest_cmd_channels.c @@ -4,7 +4,7 @@ void Test_Commands_Channels() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExecuteCommand("setChannel 5 12", 0); diff --git a/src/selftest/selftest_expandConstant.c b/src/selftest/selftest_expandConstant.c index ea8331501..8fc30770e 100644 --- a/src/selftest/selftest_expandConstant.c +++ b/src/selftest/selftest_expandConstant.c @@ -8,7 +8,7 @@ void Test_ExpandConstant() { char smallBuffer[8]; // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExpandConstantsWithinString("Hello", buffer, sizeof(buffer), 0); SELFTEST_ASSERT_STRING(buffer, "Hello"); @@ -110,6 +110,9 @@ void Test_ExpandConstant() { SELFTEST_ASSERT_STRING(ptr, "ba456"); free(ptr); + ptr = CMD_ExpandingStrdup("$CH1+$CH11"); + SELFTEST_ASSERT_STRING(ptr, "456+2022"); + free(ptr); //system("pause"); } diff --git a/src/selftest/selftest_expressions.c b/src/selftest/selftest_expressions.c index 379afea13..2232a92b0 100644 --- a/src/selftest/selftest_expressions.c +++ b/src/selftest/selftest_expressions.c @@ -4,7 +4,7 @@ void Test_Expressions_RunTests_Basic() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); // parser must be able to both handle '-' as an operation and '-' as a negative sign before number SELFTEST_ASSERT(Float_Equals(CMD_EvaluateExpression("-1",0), -1.0f)); diff --git a/src/selftest/selftest_http.c b/src/selftest/selftest_http.c index 346d62371..3341e747f 100644 --- a/src/selftest/selftest_http.c +++ b/src/selftest/selftest_http.c @@ -152,7 +152,7 @@ const char *Test_GetLastHTMLReply() { } void Test_Http_SingleRelayOnChannel1() { - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); PIN_SetPinRoleForPinIndex(9, IOR_Relay); PIN_SetPinChannelForPinIndex(9, 1); @@ -228,7 +228,7 @@ void Test_Http_SingleRelayOnChannel1() { } void Test_Http_TwoRelays() { - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); PIN_SetPinRoleForPinIndex(9, IOR_Relay); PIN_SetPinChannelForPinIndex(9, 1); @@ -299,7 +299,7 @@ void Test_Http_TwoRelays() { } void Test_Http_FourRelays() { - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); PIN_SetPinRoleForPinIndex(9, IOR_Relay); PIN_SetPinChannelForPinIndex(9, 1); @@ -525,7 +525,7 @@ StatusSTS sample from Tasmota RGBCW (5 PWMs set): */ void Test_Http_LED_SingleChannel() { - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); PIN_SetPinRoleForPinIndex(24, IOR_PWM); PIN_SetPinChannelForPinIndex(24, 1); @@ -561,7 +561,7 @@ void Test_Http_LED_SingleChannel() { } void Test_Http_LED_CW() { - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); PIN_SetPinRoleForPinIndex(24, IOR_PWM); PIN_SetPinChannelForPinIndex(24, 1); @@ -611,10 +611,16 @@ void Test_Http_LED_CW() { SELFTEST_ASSERT_JSON_VALUE_INTEGER("StatusSTS", "CT", 500); + SIM_SendFakeMQTTAndRunSimFrame_CMND("led_dimmer", "100"); + // StatusSTS contains POWER and Dimmer + Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS"); + SELFTEST_ASSERT_JSON_VALUE_INTEGER("StatusSTS", "Dimmer", 100); + SELFTEST_ASSERT_JSON_VALUE_STRING("StatusSTS", "POWER", "ON"); + SELFTEST_ASSERT_JSON_VALUE_INTEGER("StatusSTS", "CT", 500); } void Test_Http_LED_RGB() { - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); PIN_SetPinRoleForPinIndex(24, IOR_PWM); PIN_SetPinChannelForPinIndex(24, 1); diff --git a/src/selftest/selftest_http_client.c b/src/selftest/selftest_http_client.c index 91e15c248..f2fd4e8a2 100644 --- a/src/selftest/selftest_http_client.c +++ b/src/selftest/selftest_http_client.c @@ -4,7 +4,7 @@ void Test_HTTP_Client() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); PIN_SetPinRoleForPinIndex(9, IOR_Relay); diff --git a/src/selftest/selftest_if.c b/src/selftest/selftest_if.c index 965973ba3..109900f95 100644 --- a/src/selftest/selftest_if.c +++ b/src/selftest/selftest_if.c @@ -4,7 +4,7 @@ void Test_Command_If() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExecuteCommand("if 1 then \"setChannel 1 1521\"", 0); SELFTEST_ASSERT_CHANNEL(1, 1521); @@ -36,7 +36,7 @@ void Test_Command_If() { void Test_Command_If_Else() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExecuteCommand("if 1 then \"setChannel 1 1111\" else \"setChannel 2 2222\"", 0); SELFTEST_ASSERT_CHANNEL(1, 1111); diff --git a/src/selftest/selftest_led.c b/src/selftest/selftest_led.c index 54d955ec7..8064edcb1 100644 --- a/src/selftest/selftest_led.c +++ b/src/selftest/selftest_led.c @@ -4,7 +4,7 @@ void Test_LEDDriver_CW() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); // CW bulb requires two PWMs - first on channel 1, second on channel 2 // NOTE: we also support case where first PWM is on channel 0, and second on 1 @@ -68,9 +68,79 @@ void Test_LEDDriver_CW() { } + +void Test_LEDDriver_RGBCW() { + // reset whole device + SIM_ClearOBK(); + + PIN_SetPinRoleForPinIndex(24, IOR_PWM); + PIN_SetPinChannelForPinIndex(24, 1); + + PIN_SetPinRoleForPinIndex(26, IOR_PWM); + PIN_SetPinChannelForPinIndex(26, 2); + + PIN_SetPinRoleForPinIndex(9, IOR_PWM); + PIN_SetPinChannelForPinIndex(9, 3); + + PIN_SetPinRoleForPinIndex(6, IOR_PWM); + PIN_SetPinChannelForPinIndex(6, 4); + + PIN_SetPinRoleForPinIndex(7, IOR_PWM); + PIN_SetPinChannelForPinIndex(7, 5); + + CMD_ExecuteCommand("led_enableAll 1", 0); + CMD_ExecuteCommand("led_dimmer 100", 0); + // Set 100% Warm + CMD_ExecuteCommand("led_temperature 500", 0); + + printf("Channel R is %i, channel G is %i, channel B is %i, channel C is %i, channel W is %i\n", + CHANNEL_Get(1), CHANNEL_Get(2), CHANNEL_Get(3), CHANNEL_Get(4), CHANNEL_Get(5)); + SELFTEST_ASSERT_CHANNEL(1, 0); + SELFTEST_ASSERT_CHANNEL(2, 0); + SELFTEST_ASSERT_CHANNEL(3, 0); + SELFTEST_ASSERT_CHANNEL(4, 0); + SELFTEST_ASSERT_CHANNEL(5, 100); + + // Set 100% Cool + CMD_ExecuteCommand("led_temperature 154", 0); + + SELFTEST_ASSERT_CHANNEL(1, 0); + SELFTEST_ASSERT_CHANNEL(2, 0); + SELFTEST_ASSERT_CHANNEL(3, 0); + SELFTEST_ASSERT_CHANNEL(4, 100); + SELFTEST_ASSERT_CHANNEL(5, 0); + + // Set 100% Red + CMD_ExecuteCommand("led_basecolor_rgb FF0000", 0); + + SELFTEST_ASSERT_CHANNEL(1, 100); + SELFTEST_ASSERT_CHANNEL(2, 0); + SELFTEST_ASSERT_CHANNEL(3, 0); + SELFTEST_ASSERT_CHANNEL(4, 0); + SELFTEST_ASSERT_CHANNEL(5, 0); + + + // Set 100% RedGreen + CMD_ExecuteCommand("led_basecolor_rgb FFFF00", 0); + + SELFTEST_ASSERT_CHANNEL(1, 100); + SELFTEST_ASSERT_CHANNEL(2, 100); + SELFTEST_ASSERT_CHANNEL(3, 0); + SELFTEST_ASSERT_CHANNEL(4, 0); + SELFTEST_ASSERT_CHANNEL(5, 0); + + // set 50% + CMD_ExecuteCommand("led_dimmer 50", 0); + + SELFTEST_ASSERT_CHANNEL(1, 50); + SELFTEST_ASSERT_CHANNEL(2, 50); + SELFTEST_ASSERT_CHANNEL(3, 0); + SELFTEST_ASSERT_CHANNEL(4, 0); + SELFTEST_ASSERT_CHANNEL(5, 0); +} void Test_LEDDriver_RGB() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); // RGB bulb requires three PWMs - first on channel 1, second on channel 2, third on channel 3 // NOTE: we also support case where first PWM is on channel 0, and second on 1 @@ -98,6 +168,8 @@ void Test_LEDDriver_RGB() { SELFTEST_ASSERT_EXPRESSION("$led_dimmer*0.001", 0.1f); SELFTEST_ASSERT_EXPRESSION("$led_dimmer/100", 1.0f); SELFTEST_ASSERT_EXPRESSION("$led_dimmer/1000", 0.1f); + SELFTEST_ASSERT_EXPRESSION("$led_dimmer+$led_dimmer", 200.0f); + SELFTEST_ASSERT_EXPRESSION("$led_dimmer+$led_dimmer+$led_dimmer", 300.0f); printf("Channel R is %i, channel G is %i, channel B is %i\n", CHANNEL_Get(1), CHANNEL_Get(2), CHANNEL_Get(3)); SELFTEST_ASSERT_CHANNEL(1, 100); @@ -166,6 +238,7 @@ void Test_LEDDriver() { Test_LEDDriver_CW(); Test_LEDDriver_RGB(); + Test_LEDDriver_RGBCW(); } #endif diff --git a/src/selftest/selftest_lfs.c b/src/selftest/selftest_lfs.c index 753e97884..3cd4e4257 100644 --- a/src/selftest/selftest_lfs.c +++ b/src/selftest/selftest_lfs.c @@ -6,7 +6,7 @@ void Test_LFS() { char buffer[64]; // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExecuteCommand("lfsformat", 0); // send file content as POST to REST interface diff --git a/src/selftest/selftest_local.h b/src/selftest/selftest_local.h index 967e15865..950c0a7cb 100644 --- a/src/selftest/selftest_local.h +++ b/src/selftest/selftest_local.h @@ -5,6 +5,7 @@ #include "../new_cfg.h" #include "../cmnds/cmd_public.h" #include "../cmnds/cmd_local.h" +#include "../sim/sim_import.h" void SelfTest_Failed(const char *file, const char *function, int line, const char *exp); diff --git a/src/selftest/selftest_repeatingEvents.c b/src/selftest/selftest_repeatingEvents.c index 081fd5ec8..0fc05cb44 100644 --- a/src/selftest/selftest_repeatingEvents.c +++ b/src/selftest/selftest_repeatingEvents.c @@ -4,7 +4,7 @@ void Test_RepeatingEvents() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); SELFTEST_ASSERT_CHANNEL(10, 0); // NOTE: addRepeatingEvent [RepeatTime] [RepeatCount] // This should fire once due to RepeatCount 1 diff --git a/src/selftest/selftest_script.c b/src/selftest/selftest_script.c index 4fb8704ba..c14d7dc9a 100644 --- a/src/selftest/selftest_script.c +++ b/src/selftest/selftest_script.c @@ -14,7 +14,7 @@ void Test_Scripting() { char buffer[64]; // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExecuteCommand("lfsformat", 0); // put file in LittleFS diff --git a/src/selftest/selftest_tokenizer.c b/src/selftest/selftest_tokenizer.c index 4965416a5..fe1695eb5 100644 --- a/src/selftest/selftest_tokenizer.c +++ b/src/selftest/selftest_tokenizer.c @@ -4,7 +4,7 @@ void Test_Tokenizer() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); Tokenizer_TokenizeString("Hello", 0); SELFTEST_ASSERT_ARGUMENTS_COUNT(1); diff --git a/src/selftest/selftest_tuyaMCU.c b/src/selftest/selftest_tuyaMCU.c index 6e6df38ff..e677f2537 100644 --- a/src/selftest/selftest_tuyaMCU.c +++ b/src/selftest/selftest_tuyaMCU.c @@ -4,7 +4,7 @@ void Test_TuyaMCU_Basic() { // reset whole device - CMD_ExecuteCommand("clearAll", 0); + SIM_ClearOBK(); CMD_ExecuteCommand("startDriver TuyaMCU", 0); diff --git a/src/sim/Controller_Bulb.cpp b/src/sim/Controller_Bulb.cpp index f972e1351..b35c8a7b1 100644 --- a/src/sim/Controller_Bulb.cpp +++ b/src/sim/Controller_Bulb.cpp @@ -36,12 +36,8 @@ void CControllerBulb::onDrawn() { return; } float frac_bulb; - if (a->isDutyPercent(100.0f)) { - frac_bulb = a->determineLEDLightFraction(b); - } - else { - frac_bulb = b->determineLEDLightFraction(a); - } + // TODO: better calc, this is straight up wrong in most cases + frac_bulb = a->getDutyRange01() * b->getDutyRange01(); setShapesFillColor(frac_bulb * col_yellow); if (a->shouldLightUpBulb(b)) { setShapesActive(true); diff --git a/src/sim/Controller_Pot.cpp b/src/sim/Controller_Pot.cpp index 4474098bd..ee06fd5a5 100644 --- a/src/sim/Controller_Pot.cpp +++ b/src/sim/Controller_Pot.cpp @@ -2,6 +2,7 @@ #include "Controller_Pot.h" #include "Shape.h" #include "Junction.h" +#include "Text.h" CControllerPot::CControllerPot(class CJunction *_a, class CJunction *_b, class CJunction *_o) { a = _a; @@ -20,6 +21,7 @@ class CControllerBase *CControllerPot::cloneController(class CShape *origOwner, r->a = newOwner->findShapeByName_r(this->a->getName())->asJunction(); r->b = newOwner->findShapeByName_r(this->b->getName())->asJunction(); r->o = newOwner->findShapeByName_r(this->o->getName())->asJunction(); + r->display = newOwner->findShapeByName_r(this->display->getName())->asText(); return r; } class CJunction *CControllerPot::findOtherJunctionIfPassable(class CJunction *ju) { @@ -40,6 +42,20 @@ void CControllerPot::sendEvent(int code, const class Coord &mouseOfs) { frac = 1; } void CControllerPot::onDrawn() { + if (a->getVisitCount() > 0 && b->getVisitCount() > 0) { + float aVal = a->getVoltage(); + float bVal = b->getVoltage(); + float fin = aVal + (bVal - aVal) * frac; + o->setCurrentSource(true); + o->setVoltage(fin); + o->setVisitCount(1); + display->setTextf("%f", fin); + } + else { + o->setCurrentSource(false); + o->setVoltage(0); + display->setTextf("Not connected"); + } mover->setPosition(posA.lerp(posB, frac)); } diff --git a/src/sim/Controller_Pot.h b/src/sim/Controller_Pot.h index 75cc5c445..673f3e2bd 100644 --- a/src/sim/Controller_Pot.h +++ b/src/sim/Controller_Pot.h @@ -9,6 +9,7 @@ class CControllerPot : public CControllerBase { Coord posA, posB; float frac; class CShape *mover; + class CText *display; class CJunction *a, *b, *o; public: CControllerPot() { @@ -19,6 +20,9 @@ public: void setMover(CShape *p) { mover = p; } + void setDisplay(CText *p) { + display = p; + } virtual void sendEvent(int code, const class Coord &mouseOfs); virtual void onDrawn(); virtual void rotateDegreesAround(float f, const Coord &p); diff --git a/src/sim/Controller_SimulatorLink.cpp b/src/sim/Controller_SimulatorLink.cpp index 598c57404..19425a11b 100644 --- a/src/sim/Controller_SimulatorLink.cpp +++ b/src/sim/Controller_SimulatorLink.cpp @@ -22,7 +22,12 @@ void CControllerSimulatorLink::onDrawn() { float v = ju->getVoltage(); if (gpio < 0) continue; - if (SIM_IsPinPWM(gpio)) { + if (SIM_IsPinADC(gpio)) { + SIM_SetVoltageOnADCPin(gpio, v); + ju->setCurrentSource(false); + ju->setVisitCount(0); + } + else if (SIM_IsPinPWM(gpio)) { int pwm = SIM_GetPWMValue(gpio); ju->setCurrentSource(true); ju->setVoltage(3.3f); diff --git a/src/sim/PrefabManager.cpp b/src/sim/PrefabManager.cpp index 5176414ce..63498714c 100644 --- a/src/sim/PrefabManager.cpp +++ b/src/sim/PrefabManager.cpp @@ -335,8 +335,11 @@ class CShape *PrefabManager::generatePot() { o->addLine(w - 20, 40, w - 20, 20); o->addLine(-w + 20, 40, -w + 20, 20); o->addLine(-w + 80, 40, -w + 80, 20); + CShape *text_value = o->addText(0, 0, "1.23V"); + text_value->setName("text_value"); CControllerPot *pot = new CControllerPot(gnd, vdd, out); pot->setMover(handle); + pot->setDisplay(text_value->asText()); o->setController(pot); return o; } diff --git a/src/sim/Text.cpp b/src/sim/Text.cpp index c7511921f..0a1c8b630 100644 --- a/src/sim/Text.cpp +++ b/src/sim/Text.cpp @@ -72,6 +72,14 @@ bool CText::processKeyDown(int keyCode) { float CText::getFloat() const { return atof(txt.c_str()); } +void CText::setTextf(const char *fmt, ...) { + va_list argList; + char buffer[512]; + va_start(argList, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, argList); + va_end(argList); + setText(buffer); +} void CText::appendText(const char *s) { //txt.append(s); txt.insert(cursorPos, s); diff --git a/src/sim/Text.h b/src/sim/Text.h index 0f4ec46f0..0191c657f 100644 --- a/src/sim/Text.h +++ b/src/sim/Text.h @@ -48,6 +48,7 @@ public: this->txt = s; cursorPos = strlen(s); } + void setTextf(const char *s, ...); const char *getText() const { return this->txt.c_str(); } diff --git a/src/sim/sim_import.h b/src/sim/sim_import.h index 6e4d16f97..ec3199fe4 100644 --- a/src/sim/sim_import.h +++ b/src/sim/sim_import.h @@ -1,10 +1,14 @@ +#ifdef __cplusplus extern "C" { +#endif // pins control simulation void SIM_SetSimulatedPinValue(int pinIndex, bool bHigh); bool SIM_GetSimulatedPinValue(int pinIndex); bool SIM_IsPinInput(int index); bool SIM_IsPinPWM(int index); + bool SIM_IsPinADC(int index); + void SIM_SetVoltageOnADCPin(int index, float v); int SIM_GetPWMValue(int index); // flash control simulation void SIM_SetupFlashFileReading(const char *flashPath); @@ -14,4 +18,6 @@ extern "C" { void SIM_DoFreshOBKBoot(); void SIM_ClearOBK(); bool SIM_IsFlashModified(); -}; +#ifdef __cplusplus +} +#endif diff --git a/src/win_main.c b/src/win_main.c index 474f419b6..1f2df17f1 100644 --- a/src/win_main.c +++ b/src/win_main.c @@ -117,8 +117,11 @@ void Win_DoUnitTests() { Test_TuyaMCU_Basic(); } bool bObkStarted = false; +void SIM_Hack_ClearSimulatedPinRoles(); + void SIM_ClearOBK() { if (bObkStarted) { + SIM_Hack_ClearSimulatedPinRoles(); CMD_ExecuteCommand("clearAll", 0); } }