mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-28 13:46:36 +00:00
Add moodlight command
This commit is contained in:
parent
beddba6daf
commit
d73d6b19d5
@ -333,7 +333,8 @@ static void my_btnmatrix_map_create(lv_obj_t * obj, const char * payload)
|
|||||||
DeserializationError jsonError = deserializeJson(map_doc, payload);
|
DeserializationError jsonError = deserializeJson(map_doc, payload);
|
||||||
|
|
||||||
if(jsonError) { // Couldn't parse incoming JSON payload
|
if(jsonError) { // Couldn't parse incoming JSON payload
|
||||||
return Log.warning(TAG_ATTR, F("JSON: Failed to parse incoming button map with error: %s"), jsonError.c_str());
|
dispatch_json_error(TAG_ATTR, jsonError);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray arr = map_doc.as<JsonArray>(); // Parse payload
|
JsonArray arr = map_doc.as<JsonArray>(); // Parse payload
|
||||||
@ -404,7 +405,8 @@ static void line_set_points(lv_obj_t * obj, const char * payload)
|
|||||||
DeserializationError jsonError = deserializeJson(doc, payload);
|
DeserializationError jsonError = deserializeJson(doc, payload);
|
||||||
|
|
||||||
if(jsonError) { // Couldn't parse incoming JSON payload
|
if(jsonError) { // Couldn't parse incoming JSON payload
|
||||||
return Log.warning(TAG_ATTR, F("JSON: Failed to parse incoming line points with error: %s"), jsonError.c_str());
|
dispatch_json_error(TAG_ATTR, jsonError);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray arr = doc.as<JsonArray>(); // Parse payload
|
JsonArray arr = doc.as<JsonArray>(); // Parse payload
|
||||||
@ -441,7 +443,7 @@ static inline lv_color_t haspLogColor(lv_color_t color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OK
|
// OK
|
||||||
static bool haspPayloadToColor(const char * payload, lv_color_t & color)
|
bool haspPayloadToColor(const char * payload, lv_color_t & color)
|
||||||
{
|
{
|
||||||
/* HEX format #rrggbb or #rrggbbaa */
|
/* HEX format #rrggbb or #rrggbbaa */
|
||||||
char pattern[4];
|
char pattern[4];
|
||||||
|
@ -27,6 +27,8 @@ void line_clear_points(lv_obj_t * obj);
|
|||||||
void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char * payload, bool update);
|
void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char * payload, bool update);
|
||||||
bool hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, const char * payload, bool update);
|
bool hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, const char * payload, bool update);
|
||||||
|
|
||||||
|
bool haspPayloadToColor(const char * payload, lv_color_t & color);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "hasp_object.h"
|
#include "hasp_object.h"
|
||||||
#include "hasp.h"
|
#include "hasp.h"
|
||||||
#include "hasp_utilities.h"
|
#include "hasp_utilities.h"
|
||||||
|
#include "hasp_attribute.h"
|
||||||
|
|
||||||
#if HASP_USE_DEBUG > 0
|
#if HASP_USE_DEBUG > 0
|
||||||
#include "StringStream.h"
|
#include "StringStream.h"
|
||||||
@ -35,7 +36,14 @@ extern unsigned long debugLastMillis; // UpdateStatus timer
|
|||||||
extern uint8_t hasp_sleep_state;
|
extern uint8_t hasp_sleep_state;
|
||||||
|
|
||||||
uint8_t nCommands = 0;
|
uint8_t nCommands = 0;
|
||||||
haspCommand_t commands[16];
|
haspCommand_t commands[17];
|
||||||
|
|
||||||
|
struct moodlight_t
|
||||||
|
{
|
||||||
|
byte power;
|
||||||
|
byte r, g, b;
|
||||||
|
};
|
||||||
|
moodlight_t moodlight;
|
||||||
|
|
||||||
static void dispatch_config(const char * topic, const char * payload);
|
static void dispatch_config(const char * topic, const char * payload);
|
||||||
// void dispatch_group_value(uint8_t groupid, int16_t state, lv_obj_t * obj);
|
// void dispatch_group_value(uint8_t groupid, int16_t state, lv_obj_t * obj);
|
||||||
@ -77,6 +85,11 @@ bool dispatch_factory_reset()
|
|||||||
return formated && erased;
|
return formated && erased;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dispatch_json_error(uint8_t tag, DeserializationError & jsonError)
|
||||||
|
{
|
||||||
|
Log.error(tag, F("JSON parsing failed: %s"), jsonError.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// p[x].b[y].attr=value
|
// p[x].b[y].attr=value
|
||||||
inline bool dispatch_process_button_attribute(const char * topic_p, const char * payload)
|
inline bool dispatch_process_button_attribute(const char * topic_p, const char * payload)
|
||||||
{
|
{
|
||||||
@ -330,7 +343,7 @@ static void dispatch_config(const char * topic, const char * payload)
|
|||||||
} else {
|
} else {
|
||||||
DeserializationError jsonError = deserializeJson(doc, payload);
|
DeserializationError jsonError = deserializeJson(doc, payload);
|
||||||
if(jsonError) { // Couldn't parse incoming JSON command
|
if(jsonError) { // Couldn't parse incoming JSON command
|
||||||
Log.warning(TAG_MSGR, F("JSON: Failed to parse incoming JSON command with error: %s"), jsonError.c_str());
|
dispatch_json_error(TAG_MSGR, jsonError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
settings = doc.as<JsonObject>();
|
settings = doc.as<JsonObject>();
|
||||||
@ -568,7 +581,7 @@ void dispatch_parse_json(const char *, const char * payload)
|
|||||||
json.shrinkToFit();
|
json.shrinkToFit();
|
||||||
|
|
||||||
if(jsonError) { // Couldn't parse incoming JSON command
|
if(jsonError) { // Couldn't parse incoming JSON command
|
||||||
Log.warning(TAG_MSGR, F("Failed to parse incoming JSON command with error: %s"), jsonError.c_str());
|
dispatch_json_error(TAG_MSGR, jsonError);
|
||||||
|
|
||||||
} else if(json.is<JsonArray>()) { // handle json as an array of commands
|
} else if(json.is<JsonArray>()) { // handle json as an array of commands
|
||||||
JsonArray arr = json.as<JsonArray>();
|
JsonArray arr = json.as<JsonArray>();
|
||||||
@ -718,6 +731,55 @@ void dispatch_dim(const char *, const char * level)
|
|||||||
dispatch_state_msg(F("dim"), payload);
|
dispatch_state_msg(F("dim"), payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dispatch_moodlight(const char * topic, const char * payload)
|
||||||
|
{
|
||||||
|
// Set the current state
|
||||||
|
if(strlen(payload) != 0) {
|
||||||
|
|
||||||
|
size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 512;
|
||||||
|
DynamicJsonDocument json(maxsize);
|
||||||
|
|
||||||
|
// Note: Deserialization needs to be (const char *) so the objects WILL be copied
|
||||||
|
// this uses more memory but otherwise the mqtt receive buffer can get overwritten by the send buffer !!
|
||||||
|
DeserializationError jsonError = deserializeJson(json, payload);
|
||||||
|
json.shrinkToFit();
|
||||||
|
|
||||||
|
if(jsonError) { // Couldn't parse incoming JSON command
|
||||||
|
dispatch_json_error(TAG_MSGR, jsonError);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(!json[F("power")].isNull()) moodlight.power = hasp_util_is_true(json[F("power")].as<String>().c_str());
|
||||||
|
|
||||||
|
if(!json[F("r")].isNull()) moodlight.r = json[F("r")].as<uint8_t>();
|
||||||
|
if(!json[F("g")].isNull()) moodlight.r = json[F("g")].as<uint8_t>();
|
||||||
|
if(!json[F("b")].isNull()) moodlight.r = json[F("b")].as<uint8_t>();
|
||||||
|
|
||||||
|
if(!json[F("color")].isNull()) {
|
||||||
|
lv_color16_t color;
|
||||||
|
if(haspPayloadToColor(json[F("color")].as<String>().c_str(), color)) {
|
||||||
|
lv_color32_t c32;
|
||||||
|
c32.full = lv_color_to32(color);
|
||||||
|
moodlight.r = c32.ch.red;
|
||||||
|
moodlight.g = c32.ch.green;
|
||||||
|
moodlight.b = c32.ch.blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(moodlight.power)
|
||||||
|
gpio_set_moodlight(moodlight.r, moodlight.g, moodlight.b);
|
||||||
|
else
|
||||||
|
gpio_set_moodlight(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the current state
|
||||||
|
char buffer[128];
|
||||||
|
snprintf_P(buffer, sizeof(buffer),
|
||||||
|
PSTR("{\"power\":\"%u\",\"color\":\"#%02x%02x%02x\",\"r\":%u,\"g\":%u,\"b\":%u}"), moodlight.power,
|
||||||
|
moodlight.r, moodlight.g, moodlight.b, moodlight.r, moodlight.g, moodlight.b);
|
||||||
|
dispatch_state_msg(F("moodlight"), buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void dispatch_backlight(const char *, const char * payload)
|
void dispatch_backlight(const char *, const char * payload)
|
||||||
{
|
{
|
||||||
// Set the current state
|
// Set the current state
|
||||||
@ -867,6 +929,7 @@ void dispatchSetup()
|
|||||||
dispatch_add_command(PSTR("dim"), dispatch_dim);
|
dispatch_add_command(PSTR("dim"), dispatch_dim);
|
||||||
dispatch_add_command(PSTR("brightness"), dispatch_dim);
|
dispatch_add_command(PSTR("brightness"), dispatch_dim);
|
||||||
dispatch_add_command(PSTR("light"), dispatch_backlight);
|
dispatch_add_command(PSTR("light"), dispatch_backlight);
|
||||||
|
dispatch_add_command(PSTR("moodlight"), dispatch_moodlight);
|
||||||
dispatch_add_command(PSTR("calibrate"), dispatch_calibrate);
|
dispatch_add_command(PSTR("calibrate"), dispatch_calibrate);
|
||||||
dispatch_add_command(PSTR("update"), dispatch_web_update);
|
dispatch_add_command(PSTR("update"), dispatch_web_update);
|
||||||
dispatch_add_command(PSTR("reboot"), dispatch_reboot);
|
dispatch_add_command(PSTR("reboot"), dispatch_reboot);
|
||||||
|
@ -32,6 +32,7 @@ void dispatch_topic_payload(const char * topic, const char * payload);
|
|||||||
void dispatch_text_line(const char * cmnd);
|
void dispatch_text_line(const char * cmnd);
|
||||||
void dispatch_parse_jsonl(Stream & stream);
|
void dispatch_parse_jsonl(Stream & stream);
|
||||||
void dispatch_clear_page(const char * page);
|
void dispatch_clear_page(const char * page);
|
||||||
|
void dispatch_json_error(uint8_t tag, DeserializationError & jsonError);
|
||||||
|
|
||||||
// void dispatchPage(uint8_t page);
|
// void dispatchPage(uint8_t page);
|
||||||
void dispatch_page_next();
|
void dispatch_page_next();
|
||||||
|
@ -261,8 +261,8 @@ void gpioSetup()
|
|||||||
pinMode(gpioConfig[i].pin, OUTPUT);
|
pinMode(gpioConfig[i].pin, OUTPUT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HASP_GPIO_LED:
|
case HASP_GPIO_LED ... HASP_GPIO_LED_CW_INVERTED:
|
||||||
case HASP_GPIO_LED_INVERTED:
|
// case HASP_GPIO_LED_INVERTED:
|
||||||
case HASP_GPIO_PWM:
|
case HASP_GPIO_PWM:
|
||||||
case HASP_GPIO_PWM_INVERTED:
|
case HASP_GPIO_PWM_INVERTED:
|
||||||
// case HASP_GPIO_BACKLIGHT:
|
// case HASP_GPIO_BACKLIGHT:
|
||||||
@ -290,27 +290,31 @@ void gpio_set_normalized_value(hasp_gpio_config_t gpio, uint16_t state)
|
|||||||
gpio.val = state >= 0x8000U ? LOW : HIGH;
|
gpio.val = state >= 0x8000U ? LOW : HIGH;
|
||||||
digitalWrite(gpio.pin, gpio.val);
|
digitalWrite(gpio.pin, gpio.val);
|
||||||
break;
|
break;
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
case HASP_GPIO_LED:
|
case HASP_GPIO_LED:
|
||||||
|
case HASP_GPIO_LED_R:
|
||||||
|
case HASP_GPIO_LED_G:
|
||||||
|
case HASP_GPIO_LED_B:
|
||||||
case HASP_GPIO_PWM:
|
case HASP_GPIO_PWM:
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
gpio.val = map(state, 0, 0xFFFFU, 0, 4095);
|
gpio.val = map(state, 0, 0xFFFFU, 0, 4095);
|
||||||
ledcWrite(gpio.group, gpio.val); // ledChannel and value
|
ledcWrite(gpio.group, gpio.val); // ledChannel and value
|
||||||
|
#else
|
||||||
|
analogWrite(gpio.pin, map(state, 0, 0xFFFFU, 0, 1023));
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case HASP_GPIO_LED_INVERTED:
|
case HASP_GPIO_LED_INVERTED:
|
||||||
|
case HASP_GPIO_LED_R_INVERTED:
|
||||||
|
case HASP_GPIO_LED_G_INVERTED:
|
||||||
|
case HASP_GPIO_LED_B_INVERTED:
|
||||||
case HASP_GPIO_PWM_INVERTED:
|
case HASP_GPIO_PWM_INVERTED:
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
gpio.val = map(0xFFFFU - state, 0, 0xFFFFU, 0, 4095);
|
gpio.val = map(0xFFFFU - state, 0, 0xFFFFU, 0, 4095);
|
||||||
ledcWrite(gpio.group, gpio.val); // ledChannel and value
|
ledcWrite(gpio.group, gpio.val); // ledChannel and value
|
||||||
break;
|
|
||||||
#else
|
#else
|
||||||
case HASP_GPIO_LED:
|
|
||||||
case HASP_GPIO_PWM:
|
|
||||||
analogWrite(gpio.pin, map(state, 0, 0xFFFFU, 0, 1023));
|
|
||||||
break;
|
|
||||||
case HASP_GPIO_LED_INVERTED:
|
|
||||||
case HASP_GPIO_PWM_INVERTED:
|
|
||||||
analogWrite(gpio.pin, map(0xFFFFU - state, 0, 0xFFFFU, 0, 1023));
|
analogWrite(gpio.pin, map(0xFFFFU - state, 0, 0xFFFFU, 0, 1023));
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -336,6 +340,23 @@ void gpio_set_normalized_group_value(uint8_t groupid, uint16_t state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
|
||||||
|
switch(gpioConfig[i].type & 0xfe) {
|
||||||
|
case HASP_GPIO_LED_R:
|
||||||
|
gpio_set_normalized_value(gpioConfig[i], map(r, 0, 0xFF, 0, 0xFFFFU));
|
||||||
|
break;
|
||||||
|
case HASP_GPIO_LED_G:
|
||||||
|
gpio_set_normalized_value(gpioConfig[i], map(g, 0, 0xFF, 0, 0xFFFFU));
|
||||||
|
break;
|
||||||
|
case HASP_GPIO_LED_B:
|
||||||
|
gpio_set_normalized_value(gpioConfig[i], map(b, 0, 0xFF, 0, 0xFFFFU));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// not used
|
// not used
|
||||||
// void gpio_set_gpio_value(uint8_t pin, uint16_t state)
|
// void gpio_set_gpio_value(uint8_t pin, uint16_t state)
|
||||||
// {
|
// {
|
||||||
|
@ -26,6 +26,7 @@ void gpioEvery5Seconds(void);
|
|||||||
// void gpio_set_group_onoff(uint8_t groupid, bool ison);
|
// void gpio_set_group_onoff(uint8_t groupid, bool ison);
|
||||||
void gpio_set_normalized_group_value(uint8_t groupid, uint16_t state);
|
void gpio_set_normalized_group_value(uint8_t groupid, uint16_t state);
|
||||||
// void gpio_set_gpio_state(uint8_t pin, uint16_t state);
|
// void gpio_set_gpio_state(uint8_t pin, uint16_t state);
|
||||||
|
void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc);
|
bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc);
|
||||||
bool gpioIsSystemPin(uint8_t gpio);
|
bool gpioIsSystemPin(uint8_t gpio);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user