From 17d563dc5ece4e4fcf6a8b1bba3361ec6d73cdee Mon Sep 17 00:00:00 2001 From: openshwprojects Date: Fri, 15 Jul 2022 12:10:17 +0200 Subject: [PATCH] dont update if you're not sure, new led guis and better mqtt, fixes --- src/cmnds/cmd_newLEDDriver.c | 46 +++++++++-------- src/cmnds/cmd_public.h | 24 +++++++++ src/httpserver/http_fns.c | 95 +++++++++++++++++++++++++++++------- src/mqtt/new_mqtt.c | 74 ++++++++++++++++++++++------ src/mqtt/new_mqtt.h | 8 +-- src/new_pins.c | 7 +++ src/new_pins.h | 6 ++- 7 files changed, 202 insertions(+), 58 deletions(-) diff --git a/src/cmnds/cmd_newLEDDriver.c b/src/cmnds/cmd_newLEDDriver.c index 2b3607c8b..5e705330d 100644 --- a/src/cmnds/cmd_newLEDDriver.c +++ b/src/cmnds/cmd_newLEDDriver.c @@ -2,6 +2,7 @@ #include "../logging/logging.h" #include "../new_pins.h" #include "../new_cfg.h" +#include "cmd_public.h" #include "../obk_config.h" #include "../driver/drv_public.h" #include "../rgb2hsv.h" @@ -43,16 +44,6 @@ int parsePowerArgument(const char *s); -// In general, LED can be in two modes: -// - Temperature (Cool and Warm LEDs are on) -// - RGB (R G B LEDs are on) -// This is just like in Tuya. -// The third mode, "All", was added by me for testing. -enum LightMode { - Light_Temperature, - Light_RGB, - Light_All, -}; int g_lightMode = Light_RGB; // Those are base colors, normalized, without brightness applied @@ -76,9 +67,8 @@ float g_cfg_brightnessMult = 0.01f; // the slider control in the UI emits values //in the range from 154-500 (defined //in homeassistant/util/color.py as HASS_COLOR_MIN and HASS_COLOR_MAX). - -float led_temperature_min = 154.0f; -float led_temperature_max = 500.0f; +float led_temperature_min = HASS_TEMPERATURE_MIN; +float led_temperature_max = HASS_TEMPERATURE_MAX; float led_temperature_current = 0; void apply_smart_light() { @@ -149,6 +139,15 @@ static void sendColorChange() { MQTT_PublishMain_StringString("led_basecolor_rgb",s); } +void LED_GetBaseColorString(char * s) { + byte c[3]; + + c[0] = (byte)(baseColors[0]); + c[1] = (byte)(baseColors[1]); + c[2] = (byte)(baseColors[2]); + + sprintf(s,"%02X%02X%02X",c[0],c[1],c[2]); +} static void sendFinalColor() { char s[16]; byte c[3]; @@ -171,8 +170,14 @@ static void sendDimmerChange() { static void sendTemperatureChange(){ MQTT_PublishMain_StringInt("led_temperature", (int)led_temperature_current); } +float LED_GetTemperature() { + return led_temperature_current; +} +int LED_GetMode() { + return g_lightMode; +} -static void setTemperature(int tmpInteger, bool bApply) { +void LED_SetTemperature(int tmpInteger, bool bApply) { float f; led_temperature_current = tmpInteger; @@ -191,6 +196,7 @@ static void setTemperature(int tmpInteger, bool bApply) { if(bApply) { g_lightMode = Light_Temperature; + sendTemperatureChange(); apply_smart_light(); } @@ -205,9 +211,7 @@ static int temperature(const void *context, const char *cmd, const char *args, i tmp = atoi(args); - setTemperature(tmp, 1); - - sendTemperatureChange(); + LED_SetTemperature(tmp, 1); return 1; //} @@ -276,7 +280,7 @@ static int dimmer(const void *context, const char *cmd, const char *args, int cm //} //return 0; } -static int basecolor(const void *context, const char *cmd, const char *args, int bAll){ +int LED_SetBaseColor(const void *context, const char *cmd, const char *args, int bAll){ // support both '#' prefix and not const char *c = args; int val = 0; @@ -347,10 +351,10 @@ static int basecolor(const void *context, const char *cmd, const char *args, int } static int basecolor_rgb(const void *context, const char *cmd, const char *args, int cmdFlags){ - return basecolor(context,cmd,args,0); + return LED_SetBaseColor(context,cmd,args,0); } static int basecolor_rgbcw(const void *context, const char *cmd, const char *args, int cmdFlags){ - return basecolor(context,cmd,args,1); + return LED_SetBaseColor(context,cmd,args,1); } // CONFIG-ONLY command! @@ -437,7 +441,7 @@ int NewLED_InitCommands(){ CMD_RegisterCommand("led_hue", "", setHue, "set qqqq", NULL); // set, but do not apply - setTemperature(250,0); + LED_SetTemperature(250,0); // "cmnd/obk8D38570E/led_dimmer_get"" return 0; diff --git a/src/cmnds/cmd_public.h b/src/cmnds/cmd_public.h index ea703e99b..d0b37431e 100644 --- a/src/cmnds/cmd_public.h +++ b/src/cmnds/cmd_public.h @@ -43,6 +43,25 @@ enum EventCode { CMD_EVENT_MAX_TYPES }; + +// the slider control in the UI emits values +//in the range from 154-500 (defined +//in homeassistant/util/color.py as HASS_COLOR_MIN and HASS_COLOR_MAX). + +#define HASS_TEMPERATURE_MIN 154 +#define HASS_TEMPERATURE_MAX 500 + +// In general, LED can be in two modes: +// - Temperature (Cool and Warm LEDs are on) +// - RGB (R G B LEDs are on) +// This is just like in Tuya. +// The third mode, "All", was added by me for testing. +enum LightMode { + Light_Temperature, + Light_RGB, + Light_All, +}; + // cmd_tokenizer.c int Tokenizer_GetArgsCount(); const char *Tokenizer_GetArg(int i); @@ -61,9 +80,14 @@ int taslike_commands_init(); // cmd_newLEDDriver.c int NewLED_InitCommands(); float LED_GetDimmer(); +float LED_GetTemperature(); +void LED_SetTemperature(int tmpInteger, bool bApply); void LED_SetDimmer(int iVal); +int LED_SetBaseColor(const void *context, const char *cmd, const char *args, int bAll); void LED_SetEnableAll(int bEnable); int LED_GetEnableAll(); +void LED_GetBaseColorString(char * s); +int LED_GetMode(); // cmd_test.c int fortest_commands_init(); // cmd_channels.c diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index f496f91b5..0f30a1e8b 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -124,7 +124,7 @@ int http_fn_index(http_request_t *request) { char tmpA[128]; int bRawPWMs; - bRawPWMs = 0; + bRawPWMs = CFG_HasFlag(OBK_FLAG_LED_RAWCHANNELSMODE); http_setup(request, httpMimeTypeHTML); poststr(request,htmlHeader); @@ -132,7 +132,11 @@ int http_fn_index(http_request_t *request) { HTTP_AddHeader(request); if(http_getArg(request->url,"tgl",tmpA,sizeof(tmpA))) { j = atoi(tmpA); - hprintf128(request,"

Toggled %i!

",j); + if(i == SPECIAL_CHANNEL_LEDPOWER) { + hprintf128(request,"

Toggled LED power!

",j); + } else { + hprintf128(request,"

Toggled %i!

",j); + } CHANNEL_Toggle(j); } if(http_getArg(request->url,"on",tmpA,sizeof(tmpA))) { @@ -140,6 +144,11 @@ int http_fn_index(http_request_t *request) { hprintf128(request,"

Enabled %i!

",j); CHANNEL_Set(j,255,1); } + if(http_getArg(request->url,"rgb",tmpA,sizeof(tmpA))) { + hprintf128(request,"

Set RGB to %s!

",tmpA); + LED_SetBaseColor(0,"led_basecolor",tmpA,0); + } + if(http_getArg(request->url,"off",tmpA,sizeof(tmpA))) { j = atoi(tmpA); hprintf128(request,"

Disabled %i!

",j); @@ -155,8 +164,12 @@ int http_fn_index(http_request_t *request) { if(http_getArg(request->url,"dim",tmpA,sizeof(tmpA))) { int newDimmerValue = atoi(tmpA); http_getArg(request->url,"dimIndex",tmpA,sizeof(tmpA)); - j = atoi(tmpA); - hprintf128(request,"

Changed dimmer %i to %i!

",j,newDimmerValue); + j = atoi(tmpA); + if(j == SPECIAL_CHANNEL_BRIGHTNESS) { + hprintf128(request,"

Changed LED brightness to %i!

",newDimmerValue); + } else { + hprintf128(request,"

Changed dimmer %i to %i!

",j,newDimmerValue); + } CHANNEL_Set(j,newDimmerValue,1); } if(http_getArg(request->url,"set",tmpA,sizeof(tmpA))) { @@ -318,12 +331,15 @@ int http_fn_index(http_request_t *request) { } if(bRawPWMs == 0) { int c_pwms; + int lm; + + lm = LED_GetMode(); c_pwms = PIN_CountPinsWithRole(IOR_PWM); if(c_pwms > 0) { const char *c; - if(CHANNEL_Check(i)) { + if(CHANNEL_Check(SPECIAL_CHANNEL_LEDPOWER)) { c = "bgrn"; } else { c = "bred"; @@ -331,7 +347,7 @@ int http_fn_index(http_request_t *request) { poststr(request, ""); poststr(request,"
"); hprintf128(request,"",SPECIAL_CHANNEL_LEDPOWER); - hprintf128(request,"
",c,SPECIAL_CHANNEL_LEDPOWER); + hprintf128(request,"",c); poststr(request, ""); } @@ -344,6 +360,7 @@ int http_fn_index(http_request_t *request) { pwmValue = LED_GetDimmer(); poststr(request, ""); + hprintf128(request,"
LED Dimmer/Brightness
"); hprintf128(request,"
",SPECIAL_CHANNEL_BRIGHTNESS); hprintf128(request,"",inputName,SPECIAL_CHANNEL_BRIGHTNESS,pwmValue); hprintf128(request,"",inputName,SPECIAL_CHANNEL_BRIGHTNESS); @@ -358,19 +375,63 @@ int http_fn_index(http_request_t *request) { poststr(request,""); poststr(request, ""); } - if(c_pwms == 1) { - // nothing else - } else if(c_pwms == 2) { - // TODO: temperature slider - } else if(c_pwms == 3) { - // TODO: RGB sliders - - } else if(c_pwms == 4) { - // TODO: RGBW sliders? + if(c_pwms >= 3) { + char colorValue[16]; + const char *inputName = "rgb"; + const char *activeStr = ""; + if(lm == Light_RGB) { + activeStr = "[ACTIVE]"; + } - } else if(c_pwms == 5) { + LED_GetBaseColorString(colorValue); + + hprintf128(request,"
LED RGB Color %s
",activeStr); + hprintf128(request,"",SPECIAL_CHANNEL_BASECOLOR); + hprintf128(request,"",inputName,SPECIAL_CHANNEL_BASECOLOR,colorValue); + hprintf128(request,"",inputName,SPECIAL_CHANNEL_BASECOLOR); + hprintf128(request,"
"); + + + poststr(request,""); } + if(c_pwms == 2 || c_pwms == 5) { + // TODO: temperature slider + int pwmValue; + const char *inputName; + const char *activeStr = ""; + if(lm == Light_Temperature) { + activeStr = "[ACTIVE]"; + } + + inputName = "pwm"; + + pwmValue = LED_GetTemperature(); + + poststr(request, ""); + hprintf128(request,"
LED Temperature Slider %s (cur=%i, min=%i, max=%i) (Cold <--- ---> Warm)
",activeStr,pwmValue,HASS_TEMPERATURE_MIN,HASS_TEMPERATURE_MAX); + hprintf128(request,"
",SPECIAL_CHANNEL_TEMPERATURE); + hprintf128(request,"",inputName,SPECIAL_CHANNEL_TEMPERATURE,pwmValue); + hprintf128(request,"",inputName,SPECIAL_CHANNEL_TEMPERATURE); + hprintf128(request,"
",SPECIAL_CHANNEL_TEMPERATURE); + + + poststr(request,""); + poststr(request, ""); + + + } } poststr(request, ""); @@ -1447,7 +1508,7 @@ const char *g_obk_flagNames[] = { "[MQTT] Broadcast led params together (send dimmer and color when dimmer or color changes, topic name: YourDevName/led_basecolor_rgb/get, YourDevName/led_dimmer/get)", "[MQTT] Broadcast led final color (topic name: YourDevName/led_finalcolor_rgb/get)", "[MQTT] Broadcast self state every minute", - "error", + "[LED][Debug] Show raw PWM controller on WWW index instead of new LED RGB/CW/etc picker", "error", "error", "error", diff --git a/src/mqtt/new_mqtt.c b/src/mqtt/new_mqtt.c index 3b1cbfa2e..664a7c135 100644 --- a/src/mqtt/new_mqtt.c +++ b/src/mqtt/new_mqtt.c @@ -71,6 +71,25 @@ int g_bPublishAllStatesNow = 0; #define PUBLISHITEM_SELF_IP -1 int g_publishItemIndex = PUBLISHITEM_INDEX_FIRST; +static SemaphoreHandle_t g_mutex = 0; + +static bool MQTT_Mutex_Take(int del) { + int taken; + + if(g_mutex == 0) + { + g_mutex = xSemaphoreCreateMutex( ); + } + taken = xSemaphoreTake( g_mutex, del ); + if (taken == pdTRUE) { + return true; + } + return false; +} +static void MQTT_Mutex_Free() { + xSemaphoreGive( g_mutex ); +} + void MQTT_PublishWholeDeviceState() { g_bPublishAllStatesNow = 1; g_publishItemIndex = PUBLISHITEM_INDEX_FIRST; @@ -334,7 +353,7 @@ static void mqtt_pub_request_cb(void *arg, err_t result) // This is used to publish channel values in "obk0696FB33/1/get" format with numerical value, // This is also used to publish custom information with string name, // for example, "obk0696FB33/voltage/get" is used to publish voltage from the sensor -void MQTT_PublishMain(mqtt_client_t *client, const char *sChannel, const char *sVal) +static int MQTT_PublishMain(mqtt_client_t *client, const char *sChannel, const char *sVal) { char pub_topic[32]; // const char *pub_payload= "{\"temperature\": \"45.5\"}"; @@ -344,11 +363,22 @@ void MQTT_PublishMain(mqtt_client_t *client, const char *sChannel, const char *s u8_t retain = 0; /* No don't retain such crappy payload... */ const char *baseName; + + if(client==0) - return; + return 1; + + + if(MQTT_Mutex_Take(100)==0) { + addLogAdv(LOG_ERROR,LOG_FEATURE_MQTT,"MQTT_PublishMain: mutex failed for %s=%s\r\n", sChannel, sVal); + return 1; + } + + if(mqtt_client_is_connected(client)==0) { g_my_reconnect_mqtt_after_time = 5; - return; + MQTT_Mutex_Free(); + return 1; } addLogAdv(LOG_INFO,LOG_FEATURE_MQTT,"Publishing %s = %s \n",sChannel,sVal); @@ -366,6 +396,8 @@ void MQTT_PublishMain(mqtt_client_t *client, const char *sChannel, const char *s addLogAdv(LOG_INFO,LOG_FEATURE_MQTT,"Publish err: %d\n", err); } } + MQTT_Mutex_Free(); + return 0; } @@ -573,32 +605,38 @@ static void MQTT_do_connect(mqtt_client_t *client) addLogAdv(LOG_INFO,LOG_FEATURE_MQTT,"mqtt_host %s not found by gethostbyname\r\n", mqtt_host); } } -void MQTT_PublishMain_StringInt(const char *sChannel, int iv) +int MQTT_PublishMain_StringInt(const char *sChannel, int iv) { char valueStr[16]; + sprintf(valueStr,"%i",iv); - MQTT_PublishMain(mqtt_client,sChannel,valueStr); + return MQTT_PublishMain(mqtt_client,sChannel,valueStr); + } -void MQTT_PublishMain_StringFloat(const char *sChannel, float f) +int MQTT_PublishMain_StringFloat(const char *sChannel, float f) { char valueStr[16]; + sprintf(valueStr,"%f",f); - MQTT_PublishMain(mqtt_client,sChannel,valueStr); + return MQTT_PublishMain(mqtt_client,sChannel,valueStr); + } -void MQTT_PublishMain_StringString(const char *sChannel, const char *valueStr) +int MQTT_PublishMain_StringString(const char *sChannel, const char *valueStr) { - MQTT_PublishMain(mqtt_client,sChannel,valueStr); + + return MQTT_PublishMain(mqtt_client,sChannel,valueStr); + } -void MQTT_Publish_SelfIP() { +int MQTT_Publish_SelfIP() { const char *ip; ip = HAL_GetMyIPString(); - MQTT_PublishMain_StringString("IP",ip); + return MQTT_PublishMain_StringString("IP",ip); } -void MQTT_ChannelChangeCallback(int channel, int iVal) +int MQTT_ChannelChangeCallback(int channel, int iVal) { char channelNameStr[8]; char valueStr[16]; @@ -608,9 +646,9 @@ void MQTT_ChannelChangeCallback(int channel, int iVal) sprintf(channelNameStr,"%i",channel); sprintf(valueStr,"%i",iVal); - MQTT_PublishMain(mqtt_client,channelNameStr,valueStr); + return MQTT_PublishMain(mqtt_client,channelNameStr,valueStr); } -void MQTT_ChannelPublish(int channel) +int MQTT_ChannelPublish(int channel) { char channelNameStr[8]; char valueStr[16]; @@ -623,7 +661,7 @@ void MQTT_ChannelPublish(int channel) sprintf(channelNameStr,"%i",channel); sprintf(valueStr,"%i",iValue); - MQTT_PublishMain(mqtt_client,channelNameStr,valueStr); + return MQTT_PublishMain(mqtt_client,channelNameStr,valueStr); } int MQTT_PublishCommand(const void *context, const char *cmd, const char *args, int cmdFlags) { const char *topic, *value; @@ -686,6 +724,10 @@ int MQTT_RunEverySecondUpdate() { if (!mqtt_initialised) return 0; + if(MQTT_Mutex_Take(100)==0) { + return 0; + } + // if asked to reconnect (e.g. change of topic(s)) if (mqtt_reconnect > 0){ mqtt_reconnect --; @@ -710,6 +752,7 @@ int MQTT_RunEverySecondUpdate() { MQTT_do_connect(mqtt_client); loopsWithDisconnected = 0; } + MQTT_Mutex_Free(); return 0; } else { // it is connected @@ -749,6 +792,7 @@ int MQTT_RunEverySecondUpdate() { } } + MQTT_Mutex_Free(); return 1; } diff --git a/src/mqtt/new_mqtt.h b/src/mqtt/new_mqtt.h index 1dc4cfc39..33f2abd43 100644 --- a/src/mqtt/new_mqtt.h +++ b/src/mqtt/new_mqtt.h @@ -39,10 +39,10 @@ int MQTT_RemoveCallback(int ID); void MQTT_GetStats(int *outUsed, int *outMax, int *outFreeMem); -void MQTT_PublishMain_StringFloat(const char *sChannel, float f); -void MQTT_PublishMain_StringInt(const char *sChannel, int val); -void MQTT_PublishMain_StringString(const char *sChannel, const char *valueStr); -void MQTT_ChannelChangeCallback(int channel, int iVal); +int MQTT_PublishMain_StringFloat(const char *sChannel, float f); +int MQTT_PublishMain_StringInt(const char *sChannel, int val); +int MQTT_PublishMain_StringString(const char *sChannel, const char *valueStr); +int MQTT_ChannelChangeCallback(int channel, int iVal); diff --git a/src/new_pins.c b/src/new_pins.c index 87a336562..14ac92c52 100644 --- a/src/new_pins.c +++ b/src/new_pins.c @@ -530,6 +530,10 @@ void CHANNEL_Set(int ch, int iVal, int iFlags) { LED_SetDimmer(iVal); return; } + if(ch == SPECIAL_CHANNEL_TEMPERATURE) { + LED_SetTemperature(iVal,1); + return; + } if(ch < 0 || ch >= CHANNEL_MAX) { //if(bMustBeSilent==0) { addLogAdv(LOG_ERROR, LOG_FEATURE_GENERAL,"CHANNEL_Set: Channel index %i is out of range <0,%i)\n\r",ch,CHANNEL_MAX); @@ -633,6 +637,9 @@ int CHANNEL_HasChannelPinWithRole(int ch, int iorType) { return 0; } bool CHANNEL_Check(int ch) { + if(ch == SPECIAL_CHANNEL_LEDPOWER) { + return LED_GetEnableAll(); + } if(ch < 0 || ch >= CHANNEL_MAX) { addLogAdv(LOG_ERROR, LOG_FEATURE_GENERAL,"CHANNEL_Check: Channel index %i is out of range <0,%i)\n\r",ch,CHANNEL_MAX); return 0; diff --git a/src/new_pins.h b/src/new_pins.h index 08746722d..463eee690 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -66,6 +66,8 @@ enum ChannelType { #define SPECIAL_CHANNEL_BRIGHTNESS 129 #define SPECIAL_CHANNEL_LEDPOWER 130 +#define SPECIAL_CHANNEL_BASECOLOR 131 +#define SPECIAL_CHANNEL_TEMPERATURE 132 typedef struct pinsState_s { // All above values are indexed by physical pin index @@ -86,7 +88,9 @@ typedef struct pinsState_s { #define OBK_FLAG_MQTT_BROADCASTLEDPARAMSTOGETHER 0 #define OBK_FLAG_MQTT_BROADCASTLEDFINALCOLOR 1 #define OBK_FLAG_MQTT_BROADCASTSELFSTATEPERMINUTE 2 -#define OBK_TOTAL_FLAGS 3 +#define OBK_FLAG_LED_RAWCHANNELSMODE 3 + +#define OBK_TOTAL_FLAGS 4 // // Main config structure (less than 2KB)