mirror of
https://github.com/esphome/esphome.git
synced 2024-12-02 11:44:13 +01:00
165 lines
5.1 KiB
C++
165 lines
5.1 KiB
C++
#include "light_json_schema.h"
|
|
#include "light_output.h"
|
|
|
|
#ifdef USE_JSON
|
|
|
|
namespace esphome {
|
|
namespace light {
|
|
|
|
// See https://www.home-assistant.io/integrations/light.mqtt/#json-schema for documentation on the schema
|
|
|
|
void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
|
|
if (state.supports_effects())
|
|
root["effect"] = state.get_effect_name();
|
|
|
|
auto values = state.remote_values;
|
|
auto traits = state.get_output()->get_traits();
|
|
|
|
switch (values.get_color_mode()) {
|
|
case ColorMode::UNKNOWN: // don't need to set color mode if we don't know it
|
|
break;
|
|
case ColorMode::ON_OFF:
|
|
root["color_mode"] = "onoff";
|
|
break;
|
|
case ColorMode::BRIGHTNESS:
|
|
root["color_mode"] = "brightness";
|
|
break;
|
|
case ColorMode::WHITE: // not supported by HA in MQTT
|
|
root["color_mode"] = "white";
|
|
break;
|
|
case ColorMode::COLOR_TEMPERATURE:
|
|
root["color_mode"] = "color_temp";
|
|
break;
|
|
case ColorMode::COLD_WARM_WHITE: // not supported by HA
|
|
root["color_mode"] = "cwww";
|
|
break;
|
|
case ColorMode::RGB:
|
|
root["color_mode"] = "rgb";
|
|
break;
|
|
case ColorMode::RGB_WHITE:
|
|
root["color_mode"] = "rgbw";
|
|
break;
|
|
case ColorMode::RGB_COLOR_TEMPERATURE: // not supported by HA
|
|
root["color_mode"] = "rgbct";
|
|
break;
|
|
case ColorMode::RGB_COLD_WARM_WHITE:
|
|
root["color_mode"] = "rgbww";
|
|
break;
|
|
}
|
|
|
|
if (values.get_color_mode() & ColorCapability::ON_OFF)
|
|
root["state"] = (values.get_state() != 0.0f) ? "ON" : "OFF";
|
|
if (values.get_color_mode() & ColorCapability::BRIGHTNESS)
|
|
root["brightness"] = uint8_t(values.get_brightness() * 255);
|
|
|
|
JsonObject color = root.createNestedObject("color");
|
|
if (values.get_color_mode() & ColorCapability::RGB) {
|
|
color["r"] = uint8_t(values.get_color_brightness() * values.get_red() * 255);
|
|
color["g"] = uint8_t(values.get_color_brightness() * values.get_green() * 255);
|
|
color["b"] = uint8_t(values.get_color_brightness() * values.get_blue() * 255);
|
|
}
|
|
if (values.get_color_mode() & ColorCapability::WHITE) {
|
|
color["w"] = uint8_t(values.get_white() * 255);
|
|
root["white_value"] = uint8_t(values.get_white() * 255); // legacy API
|
|
}
|
|
if (values.get_color_mode() & ColorCapability::COLOR_TEMPERATURE) {
|
|
// this one isn't under the color subkey for some reason
|
|
root["color_temp"] = uint32_t(values.get_color_temperature());
|
|
}
|
|
if (values.get_color_mode() & ColorCapability::COLD_WARM_WHITE) {
|
|
color["c"] = uint8_t(values.get_cold_white() * 255);
|
|
color["w"] = uint8_t(values.get_warm_white() * 255);
|
|
}
|
|
}
|
|
|
|
void LightJSONSchema::parse_color_json(LightState &state, LightCall &call, JsonObject root) {
|
|
if (root.containsKey("state")) {
|
|
auto val = parse_on_off(root["state"]);
|
|
switch (val) {
|
|
case PARSE_ON:
|
|
call.set_state(true);
|
|
break;
|
|
case PARSE_OFF:
|
|
call.set_state(false);
|
|
break;
|
|
case PARSE_TOGGLE:
|
|
call.set_state(!state.remote_values.is_on());
|
|
break;
|
|
case PARSE_NONE:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (root.containsKey("brightness")) {
|
|
call.set_brightness(float(root["brightness"]) / 255.0f);
|
|
}
|
|
|
|
if (root.containsKey("color")) {
|
|
JsonObject color = root["color"];
|
|
// HA also encodes brightness information in the r, g, b values, so extract that and set it as color brightness.
|
|
float max_rgb = 0.0f;
|
|
if (color.containsKey("r")) {
|
|
float r = float(color["r"]) / 255.0f;
|
|
max_rgb = fmaxf(max_rgb, r);
|
|
call.set_red(r);
|
|
}
|
|
if (color.containsKey("g")) {
|
|
float g = float(color["g"]) / 255.0f;
|
|
max_rgb = fmaxf(max_rgb, g);
|
|
call.set_green(g);
|
|
}
|
|
if (color.containsKey("b")) {
|
|
float b = float(color["b"]) / 255.0f;
|
|
max_rgb = fmaxf(max_rgb, b);
|
|
call.set_blue(b);
|
|
}
|
|
if (color.containsKey("r") || color.containsKey("g") || color.containsKey("b")) {
|
|
call.set_color_brightness(max_rgb);
|
|
}
|
|
|
|
if (color.containsKey("c")) {
|
|
call.set_cold_white(float(color["c"]) / 255.0f);
|
|
}
|
|
if (color.containsKey("w")) {
|
|
// the HA scheme is ambiguous here, the same key is used for white channel in RGBW and warm
|
|
// white channel in RGBWW.
|
|
if (color.containsKey("c")) {
|
|
call.set_warm_white(float(color["w"]) / 255.0f);
|
|
} else {
|
|
call.set_white(float(color["w"]) / 255.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (root.containsKey("white_value")) { // legacy API
|
|
call.set_white(float(root["white_value"]) / 255.0f);
|
|
}
|
|
|
|
if (root.containsKey("color_temp")) {
|
|
call.set_color_temperature(float(root["color_temp"]));
|
|
}
|
|
}
|
|
|
|
void LightJSONSchema::parse_json(LightState &state, LightCall &call, JsonObject root) {
|
|
LightJSONSchema::parse_color_json(state, call, root);
|
|
|
|
if (root.containsKey("flash")) {
|
|
auto length = uint32_t(float(root["flash"]) * 1000);
|
|
call.set_flash_length(length);
|
|
}
|
|
|
|
if (root.containsKey("transition")) {
|
|
auto length = uint32_t(float(root["transition"]) * 1000);
|
|
call.set_transition_length(length);
|
|
}
|
|
|
|
if (root.containsKey("effect")) {
|
|
const char *effect = root["effect"];
|
|
call.set_effect(effect);
|
|
}
|
|
}
|
|
|
|
} // namespace light
|
|
} // namespace esphome
|
|
|
|
#endif
|