diff --git a/openBeken_win32_mvsc2017.vcxproj b/openBeken_win32_mvsc2017.vcxproj index 9c1d31dde..24f12ba29 100644 --- a/openBeken_win32_mvsc2017.vcxproj +++ b/openBeken_win32_mvsc2017.vcxproj @@ -302,6 +302,7 @@ true + true diff --git a/openBeken_win32_mvsc2017.vcxproj.filters b/openBeken_win32_mvsc2017.vcxproj.filters index 6086f6857..f86171a88 100644 --- a/openBeken_win32_mvsc2017.vcxproj.filters +++ b/openBeken_win32_mvsc2017.vcxproj.filters @@ -402,6 +402,9 @@ Simulator + + Drv + diff --git a/src/driver/drv_local.h b/src/driver/drv_local.h index 030946e48..5fd25f70b 100644 --- a/src/driver/drv_local.h +++ b/src/driver/drv_local.h @@ -50,3 +50,9 @@ bool DRV_IsRunning(const char* name); void TuyaMCU_Sensor_RunFrame(); void TuyaMCU_Sensor_Init(); + +void DRV_Toggler_ProcessChanges(http_request_t *request); +void DRV_Toggler_AddToHtmlPage(http_request_t *request); +void DRV_Toggler_AppendInformationToHTTPIndexPage(http_request_t* request); +void DRV_InitPWMToggler(); + diff --git a/src/driver/drv_main.c b/src/driver/drv_main.c index eb4b065f8..a1be90e16 100644 --- a/src/driver/drv_main.c +++ b/src/driver/drv_main.c @@ -77,6 +77,7 @@ static driver_t g_drivers[] = { //Test drivers { "TESTPOWER", Test_Power_Init, Test_Power_RunFrame, BL09XX_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false }, { "TESTLED", Test_LED_Driver_Init, Test_LED_Driver_RunFrame, NULL, NULL, NULL, Test_LED_Driver_OnChannelChanged, false }, + #if PLATFORM_BEKEN { "SM16703P", SM16703P_Init, NULL, NULL, NULL, NULL, NULL, false }, @@ -85,6 +86,7 @@ static driver_t g_drivers[] = { { "SSDP", DRV_SSDP_Init, DRV_SSDP_RunEverySecond, NULL, DRV_SSDP_RunQuickTick, DRV_SSDP_Shutdown, NULL, false }, #endif #if defined(PLATFORM_BEKEN) || defined(WINDOWS) + { "PWMToggler", DRV_InitPWMToggler, NULL, DRV_Toggler_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false }, { "DGR", DRV_DGR_Init, DRV_DGR_RunEverySecond, NULL, DRV_DGR_RunQuickTick, DRV_DGR_Shutdown, DRV_DGR_OnChannelChanged, false }, #endif { "SM2135", SM2135_Init, SM2135_RunFrame, NULL, NULL, NULL, SM2135_OnChannelChanged, false }, diff --git a/src/driver/drv_pwmToggler.c b/src/driver/drv_pwmToggler.c new file mode 100644 index 000000000..99ca99d22 --- /dev/null +++ b/src/driver/drv_pwmToggler.c @@ -0,0 +1,284 @@ +#include "../new_common.h" +#include "../new_pins.h" +#include "../new_cfg.h" +// Commands register, execution API and cmd tokenizer +#include "../cmnds/cmd_public.h" +#include "../mqtt/new_mqtt.h" +#include "../logging/logging.h" +#include "../hal/hal_pins.h" +#include "drv_public.h" +#include "drv_local.h" +#include "drv_uart.h" +#include "../httpserver/new_http.h" + +/* +PWM toggler provides you an abstraction layer over PWM channels +and allows you to enable/disable them without losing the set PWM value. + +PWM toggler was created to support lamp with RGB LED and PWM laser and PWM motor. + +Configuration: +- set channels 1, 2 and 3 for RGB +- enable "force RGB mode" in General/Flags +- set channels 4 for motor and 5 for laser +- on web panel, create autoexec.bat with following script: + + // enable toggler driver + startDriver PWMToggler + // toggler slot 0 will be channel 4 + toggler_channel0 4 + // toggler slot 0 display name is laser + toggler_name0 Laser + + // toggler slot 1 will be channel 5 + toggler_channel1 5 + // toggler slot 1 display name is motor + toggler_name1 Motor + +- for HA, configure RGB as usual in Yaml +- also add yaml entries for laser and motor: + + - unique_id: "OpenBK7231T_760BF030_galaxy_laser" + name: "GenioLaser" + command_topic: "cmnd/obk760BF030/toggler_enable0" + state_topic: "obk760BF030/toggler_enable0/get" + payload_on: 1 + payload_off: 0 + brightness_command_topic: "cmnd/obk760BF030/toggler_set0" + brightness_scale: 100 + brightness_state_topic: "obk760BF030/toggler_set0/get" + brightness_value_template: "{{value}}" + qos: 1 + + + + + +*/ + +#define MAX_ONOFF_SLOTS 6 + +static char *g_names[MAX_ONOFF_SLOTS] = { 0 }; +static int g_channels[MAX_ONOFF_SLOTS]; +static int g_values[MAX_ONOFF_SLOTS]; +static bool g_enabled[MAX_ONOFF_SLOTS]; + +int parsePowerArgument(const char *s); + +void publish_enableState(int index) { + char topic[32]; + snprintf(topic, sizeof(topic), "toggler_enable%i", index); + + MQTT_PublishMain_StringInt(topic, g_enabled[index]); +} +void publish_value(int index) { + char topic[32]; + snprintf(topic, sizeof(topic), "toggler_set%i", index); + + MQTT_PublishMain_StringInt(topic, g_values[index]); +} +void apply(int index) { + if (g_enabled[index]) { + CHANNEL_Set(g_channels[index], g_values[index], 0); + } + else { + CHANNEL_Set(g_channels[index], 0, 0); + } + publish_enableState(index); + publish_value(index); +} +void Toggler_Set(int index, int value) { + g_values[index] = value; + apply(index); +} +void Toggler_Toggle(int index) { + g_enabled[index] = !g_enabled[index]; + apply(index); +} +commandResult_t Toggler_NameX(const void *context, const char *cmd, const char *args, int cmdFlags) { + const char *indexStr; + int index; + bool bEnabled; + + if (args == 0 || *args == 0) { + addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "This command needs one argument"); + return CMD_RES_NOT_ENOUGH_ARGUMENTS; + } + + indexStr = cmd + strlen("toggler_name"); + index = atoi(indexStr); + + if (g_names[index]) + free(g_names[index]); + g_names[index] = strdup(args); + + return CMD_RES_OK; +} +commandResult_t Toggler_EnableX(const void *context, const char *cmd, const char *args, int cmdFlags) { + const char *indexStr; + int index; + bool bEnabled; + + if (args == 0 || *args == 0) { + addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "This command needs one argument"); + return CMD_RES_NOT_ENOUGH_ARGUMENTS; + } + + indexStr = cmd + strlen("toggler_enable"); + index = atoi(indexStr); + + bEnabled = parsePowerArgument(args); + g_enabled[index] = bEnabled; + + apply(index); + + + return CMD_RES_OK; +} + +commandResult_t Toggler_SetX(const void *context, const char *cmd, const char *args, int cmdFlags) { + const char *indexStr; + int index; + bool bEnabled; + + if (args == 0 || *args == 0) { + addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "This command needs one argument"); + return CMD_RES_NOT_ENOUGH_ARGUMENTS; + } + + indexStr = cmd + strlen("toggler_set"); + index = atoi(indexStr); + + g_values[index] = atoi(args); + + apply(index); + + + return CMD_RES_OK; +} +commandResult_t Toggler_ChannelX(const void *context, const char *cmd, const char *args, int cmdFlags) { + const char *indexStr; + int index; + bool bEnabled; + + if (args == 0 || *args == 0) { + addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "This command needs one argument"); + return CMD_RES_NOT_ENOUGH_ARGUMENTS; + } + + indexStr = cmd + strlen("toggler_channel"); + index = atoi(indexStr); + + g_channels[index] = atoi(args); + + return CMD_RES_OK; +} +const char *Toggler_GetName(int i) { + const char *name = g_names[i]; + if (name == 0) + name = "Unnamed"; + return name; +} +void DRV_Toggler_ProcessChanges(http_request_t *request) { + int j; + int val; + char tmpA[8]; + + if (http_getArg(request->url, "togglerOn", tmpA, sizeof(tmpA))) { + j = atoi(tmpA); + const char *name = Toggler_GetName(j); + hprintf255(request, "

Toggled %s!

", name); + Toggler_Toggle(j); + } + if (http_getArg(request->url, "togglerValueID", tmpA, sizeof(tmpA))) { + j = atoi(tmpA); + const char *name = Toggler_GetName(j); + http_getArg(request->url, "togglerValue", tmpA, sizeof(tmpA)); + val = atoi(tmpA); + Toggler_Set(j, val); + hprintf255(request, "

Set value %i for %s!

", val, name); + } + +} +void DRV_Toggler_AddToHtmlPage(http_request_t *request) { + int i; + const char *c; + + for (i = 0; i < MAX_ONOFF_SLOTS; i++) { + const char *name = Toggler_GetName(i); + int maxValue = 100; + if (g_channels[i] == -1) + continue; + + //hprintf255(request, " Toggler %s",name); + + hprintf255(request, ""); + if (g_enabled[i]) { + c = "bgrn"; + } + else { + c = "bred"; + } + poststr(request, "
"); + hprintf255(request, "", i); + hprintf255(request, "
", c, name); + poststr(request, ""); + + poststr(request, ""); + hprintf255(request, "
", i); + hprintf255(request, "", + maxValue, g_values[i]); + hprintf255(request, "", i); + hprintf255(request, "
", name); + poststr(request, ""); + + } +} +void DRV_Toggler_AppendInformationToHTTPIndexPage(http_request_t* request) { + int i; + hprintf255(request, "

Toggler: "); + int cnt = 0; + for (i = 0; i < MAX_ONOFF_SLOTS; i++) { + if (g_channels[i] == -1) + continue; + if (cnt != 0) { + hprintf255(request, ", "); + } + const char *name = Toggler_GetName(i); + const char *st; + if (g_enabled[i]) + st = "ON"; + else + st = "OFF"; + hprintf255(request, "slot %i-%s (target %i) has value %i, state %s", + i, name, g_channels[i], g_values[i],st); + cnt++; + } + hprintf255(request, "

"); + +} +void DRV_InitPWMToggler() { + int i; + + for (i = 0; i < MAX_ONOFF_SLOTS; i++) { + g_channels[i] = -1; + g_names[i] = 0; + } + // sets the given output ON or OFF + // handles toggler_enable0, toggler_enable1, etc + CMD_RegisterCommand("toggler_enable", "", Toggler_EnableX, NULL, NULL); + // sets the VALUE of given output + // handles toggler_set0, toggler_set1, etc + CMD_RegisterCommand("toggler_set", "", Toggler_SetX, NULL, NULL); + // handles toggler_channel0, toggler_channel1 + CMD_RegisterCommand("toggler_channel", "", Toggler_ChannelX, NULL, NULL); + // handles toggler_name0 etc + CMD_RegisterCommand("toggler_name", "", Toggler_NameX, NULL, NULL); +} + + + + + + + diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index a75ff3aed..92b3010f0 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -225,6 +225,11 @@ int http_fn_index(http_request_t* request) { http_html_start(request, NULL); poststr(request, "
"); +#if defined(PLATFORM_BEKEN) || defined(WINDOWS) + if (DRV_IsRunning("PWMToggler")) { + DRV_Toggler_ProcessChanges(request); + } +#endif if (http_getArg(request->url, "tgl", tmpA, sizeof(tmpA))) { j = atoi(tmpA); if (j == SPECIAL_CHANNEL_LEDPOWER) { @@ -694,6 +699,12 @@ int http_fn_index(http_request_t* request) { } } +#if defined(PLATFORM_BEKEN) || defined(WINDOWS) + if (DRV_IsRunning("PWMToggler")) { + DRV_Toggler_AddToHtmlPage(request); + } +#endif + poststr(request, ""); #ifndef OBK_DISABLE_ALL_DRIVERS DRV_AppendInformationToHTTPIndexPage(request);