dont update if you're not sure, new led guis and better mqtt, fixes

This commit is contained in:
openshwprojects
2022-07-15 12:10:17 +02:00
parent adb2243c3c
commit 17d563dc5e
7 changed files with 202 additions and 58 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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,"<h3>Toggled %i!</h3>",j);
if(i == SPECIAL_CHANNEL_LEDPOWER) {
hprintf128(request,"<h3>Toggled LED power!</h3>",j);
} else {
hprintf128(request,"<h3>Toggled %i!</h3>",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,"<h3>Enabled %i!</h3>",j);
CHANNEL_Set(j,255,1);
}
if(http_getArg(request->url,"rgb",tmpA,sizeof(tmpA))) {
hprintf128(request,"<h3>Set RGB to %s!</h3>",tmpA);
LED_SetBaseColor(0,"led_basecolor",tmpA,0);
}
if(http_getArg(request->url,"off",tmpA,sizeof(tmpA))) {
j = atoi(tmpA);
hprintf128(request,"<h3>Disabled %i!</h3>",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,"<h3>Changed dimmer %i to %i!</h3>",j,newDimmerValue);
j = atoi(tmpA);
if(j == SPECIAL_CHANNEL_BRIGHTNESS) {
hprintf128(request,"<h3>Changed LED brightness to %i!</h3>",newDimmerValue);
} else {
hprintf128(request,"<h3>Changed dimmer %i to %i!</h3>",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, "<tr>");
poststr(request,"<td><form action=\"index\">");
hprintf128(request,"<input type=\"hidden\" name=\"tgl\" value=\"%i\">",SPECIAL_CHANNEL_LEDPOWER);
hprintf128(request,"<input class=\"%s\" type=\"submit\" value=\"Toggle %i\"/></form></td>",c,SPECIAL_CHANNEL_LEDPOWER);
hprintf128(request,"<input class=\"%s\" type=\"submit\" value=\"Toggle Light\"/></form></td>",c);
poststr(request, "</tr>");
}
@@ -344,6 +360,7 @@ int http_fn_index(http_request_t *request) {
pwmValue = LED_GetDimmer();
poststr(request, "<tr>");
hprintf128(request,"<h5> LED Dimmer/Brightness </h5>");
hprintf128(request,"<form action=\"index\" id=\"form%i\">",SPECIAL_CHANNEL_BRIGHTNESS);
hprintf128(request,"<input type=\"range\" min=\"0\" max=\"100\" name=\"%s\" id=\"slider%i\" value=\"%i\">",inputName,SPECIAL_CHANNEL_BRIGHTNESS,pwmValue);
hprintf128(request,"<input type=\"hidden\" name=\"%sIndex\" value=\"%i\">",inputName,SPECIAL_CHANNEL_BRIGHTNESS);
@@ -358,19 +375,63 @@ int http_fn_index(http_request_t *request) {
poststr(request,"</script>");
poststr(request, "</tr>");
}
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,"<h5> LED RGB Color %s </h5>",activeStr);
hprintf128(request,"<form action=\"index\" id=\"form%i\">",SPECIAL_CHANNEL_BASECOLOR);
hprintf128(request,"<input type=\"color\" name=\"%s\" id=\"color%i\" value=\"#%s\">",inputName,SPECIAL_CHANNEL_BASECOLOR,colorValue);
hprintf128(request,"<input type=\"hidden\" name=\"%sIndex\" value=\"%i\">",inputName,SPECIAL_CHANNEL_BASECOLOR);
hprintf128(request,"<input type=\"submit\" style=\"display:none;\" value=\"Toggle Light\"/></form>");
poststr(request,"<script>");
hprintf128(request,"var color = document.getElementById(\"color%i\");\n",SPECIAL_CHANNEL_BASECOLOR);
poststr(request,"color.onchange = function () {\n");
hprintf128(request," document.getElementById(\"form%i\").submit();\n",SPECIAL_CHANNEL_BASECOLOR);
poststr(request,"}\n");
poststr(request,"</script>");
}
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, "<tr>");
hprintf128(request,"<h5> LED Temperature Slider %s (cur=%i, min=%i, max=%i) (Cold <--- ---> Warm) </h5>",activeStr,pwmValue,HASS_TEMPERATURE_MIN,HASS_TEMPERATURE_MAX);
hprintf128(request,"<form action=\"index\" id=\"form%i\">",SPECIAL_CHANNEL_TEMPERATURE);
hprintf128(request,"<input type=\"range\" min=\"%i\" max=\"%i\"", HASS_TEMPERATURE_MIN,HASS_TEMPERATURE_MAX);
hprintf128(request,"name=\"%s\" id=\"slider%i\" value=\"%i\">",inputName,SPECIAL_CHANNEL_TEMPERATURE,pwmValue);
hprintf128(request,"<input type=\"hidden\" name=\"%sIndex\" value=\"%i\">",inputName,SPECIAL_CHANNEL_TEMPERATURE);
hprintf128(request,"<input type=\"submit\" style=\"display:none;\" value=\"Toggle %i\"/></form>",SPECIAL_CHANNEL_TEMPERATURE);
poststr(request,"<script>");
hprintf128(request,"var slider = document.getElementById(\"slider%i\");\n",SPECIAL_CHANNEL_TEMPERATURE);
poststr(request,"slider.onmouseup = function () {\n");
hprintf128(request," document.getElementById(\"form%i\").submit();\n",SPECIAL_CHANNEL_TEMPERATURE);
poststr(request,"}\n");
poststr(request,"</script>");
poststr(request, "</tr>");
}
}
poststr(request, "</table>");
@@ -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",

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)