Merge pull request #14703 from s-hadinger/berry_light_state

Berry add light_state class
This commit is contained in:
s-hadinger 2022-02-02 22:16:55 +01:00 committed by GitHub
commit 51ef4078b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1509 additions and 1031 deletions

View File

@ -145,6 +145,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef ESP32
extern void be_load_tasmota_ntvlib(bvm *vm);
extern void be_load_light_state_class(bvm *vm);
extern void be_load_wirelib(bvm *vm);
extern void be_load_onewirelib(bvm *vm);
extern void be_load_serial_lib(bvm *vm);
@ -196,6 +197,9 @@ BERRY_API void be_load_custom_libs(bvm *vm)
be_load_md5_lib(vm);
be_load_serial_lib(vm);
be_load_ctypes_lib(vm);
#ifdef USE_LIGHT
be_load_light_state_class(vm);
#endif
#ifdef USE_ALEXA_AVS
be_load_crypto_lib(vm);
#endif

View File

@ -36,6 +36,8 @@ extern const bcstring be_const_str_CFG_X3A_X20running_X20;
extern const bcstring be_const_str_CFG_X3A_X20skipping_X20_X27display_X2Eini_X27_X20because_X20already_X20present_X20in_X20file_X2Dsystem;
extern const bcstring be_const_str_COLOR_BLACK;
extern const bcstring be_const_str_COLOR_WHITE;
extern const bcstring be_const_str_CT;
extern const bcstring be_const_str_DIMMER;
extern const bcstring be_const_str_EC_C25519;
extern const bcstring be_const_str_EVENT_DELETE;
extern const bcstring be_const_str_EVENT_DRAW_MAIN;
@ -62,6 +64,9 @@ extern const bcstring be_const_str_PART_MAIN;
extern const bcstring be_const_str_POST;
extern const bcstring be_const_str_Parameter_X20error;
extern const bcstring be_const_str_RES_OK;
extern const bcstring be_const_str_RGB;
extern const bcstring be_const_str_RGBCT;
extern const bcstring be_const_str_RGBW;
extern const bcstring be_const_str_Restart_X201;
extern const bcstring be_const_str_SERIAL_5E1;
extern const bcstring be_const_str_SERIAL_5E2;
@ -493,6 +498,7 @@ extern const bcstring be_const_str_last_modified;
extern const bcstring be_const_str_leds;
extern const bcstring be_const_str_length_X20in_X20bits_X20must_X20be_X20between_X200_X20and_X2032;
extern const bcstring be_const_str_light;
extern const bcstring be_const_str_light_state;
extern const bcstring be_const_str_line_dsc;
extern const bcstring be_const_str_list;
extern const bcstring be_const_str_list_handlers;
@ -655,21 +661,26 @@ extern const bcstring be_const_str_set_bits_per_sample;
extern const bcstring be_const_str_set_bri;
extern const bcstring be_const_str_set_channels;
extern const bcstring be_const_str_set_chg_current;
extern const bcstring be_const_str_set_ct;
extern const bcstring be_const_str_set_dc_voltage;
extern const bcstring be_const_str_set_dcdc_enable;
extern const bcstring be_const_str_set_exten;
extern const bcstring be_const_str_set_first_time;
extern const bcstring be_const_str_set_gain;
extern const bcstring be_const_str_set_height;
extern const bcstring be_const_str_set_huesat;
extern const bcstring be_const_str_set_ldo_enable;
extern const bcstring be_const_str_set_ldo_voltage;
extern const bcstring be_const_str_set_light;
extern const bcstring be_const_str_set_matrix_pixel_color;
extern const bcstring be_const_str_set_mode_ct;
extern const bcstring be_const_str_set_mode_rgb;
extern const bcstring be_const_str_set_percentage;
extern const bcstring be_const_str_set_pixel_color;
extern const bcstring be_const_str_set_power;
extern const bcstring be_const_str_set_pwm;
extern const bcstring be_const_str_set_rate;
extern const bcstring be_const_str_set_rgb;
extern const bcstring be_const_str_set_style_bg_color;
extern const bcstring be_const_str_set_style_line_color;
extern const bcstring be_const_str_set_style_pad_right;
@ -681,6 +692,7 @@ extern const bcstring be_const_str_set_timer;
extern const bcstring be_const_str_set_useragent;
extern const bcstring be_const_str_set_width;
extern const bcstring be_const_str_set_x;
extern const bcstring be_const_str_set_xy;
extern const bcstring be_const_str_set_y;
extern const bcstring be_const_str_setbits;
extern const bcstring be_const_str_seti;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_light_state_map) {
{ be_const_key(set_huesat, -1), be_const_ctype_func(ls_set_huesat) },
{ be_const_key(RGBCT, -1), be_const_int(5) },
{ be_const_key(set_mode_rgb, -1), be_const_ctype_func(ls_set_mode_rgb) },
{ be_const_key(set_xy, -1), be_const_ctype_func(ls_set_xy) },
{ be_const_key(set_power, -1), be_const_ctype_func(ls_set_power) },
{ be_const_key(gamma8, -1), be_const_ctype_func(ls_gamma8) },
{ be_const_key(_p, -1), be_const_var(0) },
{ be_const_key(gamma10, 8), be_const_ctype_func(ls_gamma10) },
{ be_const_key(reverse_gamma10, -1), be_const_ctype_func(ls_rev_gamma10) },
{ be_const_key(RGB, -1), be_const_int(3) },
{ be_const_key(get, 17), be_const_func(light_state_get) },
{ be_const_key(member, -1), be_const_func(light_state_member) },
{ be_const_key(set_mode_ct, 0), be_const_ctype_func(ls_set_mode_ct) },
{ be_const_key(init, -1), be_const_ctype_func(ls_init) },
{ be_const_key(CT, 4), be_const_int(2) },
{ be_const_key(DIMMER, 10), be_const_int(1) },
{ be_const_key(set_ct, 1), be_const_ctype_func(ls_set_ct) },
{ be_const_key(RGBW, -1), be_const_int(4) },
{ be_const_key(set_rgb, -1), be_const_ctype_func(ls_set_rgb) },
};
static be_define_const_map(
be_class_light_state_map,
19
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_light_state,
1,
NULL,
light_state
);

View File

@ -139,6 +139,7 @@ int be_find_global_or_module_member(bvm *vm, const char * name) {
* relevant Berry object depending on this char:
* '' (default): nil, no value
* 'i' be_int
* 'f' be_real (float)
* 'b' be_bool
* 's' be_str
* '&' bytes() object, pointer to buffer returned, and size passed with an additional (size_t*) argument
@ -465,6 +466,7 @@ int be_call_c_func(bvm *vm, const void * func, const char * return_type, const c
switch (return_type[0]) {
case '.': // fallback next
case 'i': be_pushint(vm, ret); break;
case 'f': be_pushreal(vm, intasreal(ret)); break;
case 'b': be_pushbool(vm, ret); break;
case 'c': be_pushcomptr(vm, (void*) ret); break;
case 's': be_pushstring(vm, (const char*) ret); break;

View File

@ -0,0 +1,106 @@
/********************************************************************
* Light_state class - abstract light state
*
* Handles all states and events for a virtual light.
* Can be eventually subclassed to handle a physical light.
*
*******************************************************************/
#ifdef USE_LIGHT
#include "be_constobj.h"
#include "be_mapping.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
extern void * ls_init(int32_t channels); BE_FUNC_CTYPE_DECLARE(ls_init, "+_p", "i")
extern void ls_set_rgb(void* p, int32_t r, int32_t g, int32_t b); BE_FUNC_CTYPE_DECLARE(ls_set_rgb, "", ".iii")
extern void ls_set_huesat(void* p, int32_t hue, int32_t sat); BE_FUNC_CTYPE_DECLARE(ls_set_huesat, "", ".ii")
extern void ls_set_ct(void* p, int32_t ct); BE_FUNC_CTYPE_DECLARE(ls_set_ct, "", ".i")
extern void ls_set_xy(void* p, float x, float y); BE_FUNC_CTYPE_DECLARE(ls_set_xy, "", ".ff")
extern int32_t ls_r(void* p); BE_VAR_CTYPE_DECLARE(ls_r, "i");
extern int32_t ls_g(void* p); BE_VAR_CTYPE_DECLARE(ls_g, "i");
extern int32_t ls_b(void* p); BE_VAR_CTYPE_DECLARE(ls_b, "i");
extern float ls_x(void* p); BE_VAR_CTYPE_DECLARE(ls_x, "f");
extern float ls_y(void* p); BE_VAR_CTYPE_DECLARE(ls_y, "f");
extern int32_t ls_hue(void* p); BE_VAR_CTYPE_DECLARE(ls_hue, "i");
extern int32_t ls_sat(void* p); BE_VAR_CTYPE_DECLARE(ls_sat, "i");
extern int32_t ls_bri(void* p); BE_VAR_CTYPE_DECLARE(ls_bri, "i");
extern int32_t ls_ct(void* p); BE_VAR_CTYPE_DECLARE(ls_ct, "i");
extern int32_t ls_mode_rgb(void* p); BE_VAR_CTYPE_DECLARE(ls_mode_rgb, "b");
extern int32_t ls_mode_ct(void* p); BE_VAR_CTYPE_DECLARE(ls_mode_ct, "b");
extern void ls_set_mode_rgb(void* p); BE_FUNC_CTYPE_DECLARE(ls_set_mode_rgb, "", ".");
extern void ls_set_mode_ct(void* p); BE_FUNC_CTYPE_DECLARE(ls_set_mode_ct, "", ".");
extern int32_t ls_get_power(void* p); BE_VAR_CTYPE_DECLARE(ls_get_power, "b");
extern void ls_set_power(void* p, int32_t pow); BE_FUNC_CTYPE_DECLARE(ls_set_power, "", ".b");
extern int32_t ls_gamma8(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_gamma8, "i", "-i")
extern int32_t ls_gamma10(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_gamma10, "i", "-i")
extern int32_t ls_rev_gamma10(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_rev_gamma10, "i", "-i")
const be_const_member_t light_state_members[] = {
{ ">b", be_ctype(ls_b) },
{ ">bri", be_ctype(ls_bri) },
{ ">ct", be_ctype(ls_ct) },
{ ">g", be_ctype(ls_g) },
{ ">hue", be_ctype(ls_hue) },
{ ">mode_ct", be_ctype(ls_mode_ct) },
{ ">mode_rgb", be_ctype(ls_mode_rgb) },
{ ">power", be_ctype(ls_get_power) },
{ ">r", be_ctype(ls_r) },
{ ">sat", be_ctype(ls_sat) },
{ ">x", be_ctype(ls_x) },
{ ">y", be_ctype(ls_y) },
};
extern "C" int light_state_get(bvm *vm);
static int light_state_member(bvm *vm) {
if (be_const_class_member(vm, light_state_members, ARRAY_SIZE(light_state_members))) {
be_return(vm);
} else {
be_return_nil(vm);
}
}
#include "be_fixed_be_class_light_state.h"
extern "C" void be_load_light_state_class(bvm *vm) {
be_pushntvclass(vm, &be_class_light_state);
be_setglobal(vm, "light_state");
be_pop(vm, 1);
}
/* @const_object_info_begin
class be_class_light_state (scope: global, name: light_state) {
DIMMER, int(1)
CT, int(2)
RGB, int(3)
RGBW, int(4)
RGBCT, int(5)
_p, var
init, ctype_func(ls_init)
member, func(light_state_member)
set_rgb, ctype_func(ls_set_rgb)
set_huesat, ctype_func(ls_set_huesat)
set_xy, ctype_func(ls_set_xy)
set_ct, ctype_func(ls_set_ct)
set_mode_rgb, ctype_func(ls_set_mode_rgb)
set_mode_ct, ctype_func(ls_set_mode_ct)
set_power, ctype_func(ls_set_power)
get, func(light_state_get)
gamma8, ctype_func(ls_gamma8)
gamma10, ctype_func(ls_gamma10)
reverse_gamma10, ctype_func(ls_rev_gamma10)
}
@const_object_info_end */
#endif // USE_LIGHT

View File

@ -0,0 +1,75 @@
# tests for light_state
l = light_state(light_state.RGBW)
print(l)
l.set_rgb(10,20,30)
assert(l.r == 10)
assert(l.g == 20)
assert(l.b == 30)
assert(l.hue == 211)
assert(l.sat == 169)
assert(l.bri == 30)
assert(l.power == false)
l.set_power(true)
assert(l.power == true)
# light.get()
#{'bri': 102, 'hue': 0, 'power': false, 'sat': 77, 'rgb': '664747', 'channels': [102, 71, 71]}
l.set_huesat(100,200)
assert(l.hue == 100)
assert(l.sat == 200)
assert(l.bri == 30)
assert(l.r == 14)
assert(l.g == 30)
assert(l.b == 6)
assert(l.mode_rgb)
l.set_ct(400)
assert(l.ct == 400)
assert(l.mode_ct)
# assert(l.x == 0.215944)
# assert(l.y == 0.700957)
l.set_xy(0.3, 0.4)
# red
r = light_state(light_state.RGB)
r.set_rgb(255,0,0)
assert(r.hue == 0)
assert(r.sat == 255)
assert(r.bri == 255)
# x/y = 0.735 / 0.265
b = light_state(light_state.RGB)
b.set_rgb(0,0,255)
# x/y 0.157 / 0.018
y = light_state(light_state.RGB)
y.set_rgb(255,255,0)
# x/y 0.422332 0.547914
c = light_state(light_state.RGB)
c.set_xy(0.422, 0.548)
# 5 channels
l = light_state(light_state.RGBCT)
l.set_rgb(30,40,90)
assert(str(l.get()) == "{'mode_ct': false, 'hue': 230, 'rgb': '1E285A', 'bri': 90, 'channels': [30, 40, 90, 0, 0], 'mode_rgb': true, 'sat': 170}")
l.set_ct(340)
assert(str(l.get()) == "{'bri': 90, 'ct': 340, 'mode_ct': true, 'mode_rgb': false, 'channels': [0, 0, 0, 42, 48]}")

View File

@ -345,6 +345,7 @@ class LightStateClass {
uint8_t _briCT_orig = 255;
uint8_t _color_mode = LCM_RGB; // RGB by default
bool _power = false; // power indicator, used only in virtual lights, Tasmota tracks power separately
public:
LightStateClass() {
@ -354,6 +355,9 @@ class LightStateClass {
void setSubType(uint8_t sub_type) {
_subtype = sub_type; // set sub_type at initialization, shoudln't be changed afterwards
}
uint8_t getSubType(void) const {
return _subtype;
}
// This function is a bit hairy, it will try to match the required
// colormode with the features of the device:
@ -400,19 +404,27 @@ class LightStateClass {
return prev_cm;
}
inline uint8_t getColorMode() {
inline uint8_t getColorMode() const {
return _color_mode;
}
void addRGBMode() {
void addRGBMode(void) {
setColorMode(_color_mode | LCM_RGB);
}
void addCTMode() {
void addCTMode(void) {
setColorMode(_color_mode | LCM_CT);
}
// power accessors, for virtual lights only (has no effect on Tasmota lights)
bool getPower(void) const {
return _power;
}
void setPower(bool pow) {
_power = pow;
}
// Get RGB color, always at full brightness (ie. one of the components is 255)
void getRGB(uint8_t *r, uint8_t *g, uint8_t *b) {
void getRGB(uint8_t *r, uint8_t *g, uint8_t *b) const {
if (r) { *r = _r; }
if (g) { *g = _g; }
if (b) { *b = _b; }
@ -420,13 +432,13 @@ class LightStateClass {
// get full brightness values for warm and cold channels.
// either w=c=0 (off) or w+c >= 255
void getCW(uint8_t *rc, uint8_t *rw) {
void getCW(uint8_t *rc, uint8_t *rw) const {
if (rc) { *rc = _wc; }
if (rw) { *rw = _ww; }
}
// Get the actual values for each channel, ie multiply with brightness
void getActualRGBCW(uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *c, uint8_t *w) {
void getActualRGBCW(uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *c, uint8_t *w) const {
bool rgb_channels_on = _color_mode & LCM_RGB;
bool ct_channels_on = _color_mode & LCM_CT;
@ -438,11 +450,11 @@ class LightStateClass {
if (w) { *w = ct_channels_on ? changeUIntScale(_ww, 0, 255, 0, _briCT) : 0; }
}
void getChannels(uint8_t *channels) {
void getChannels(uint8_t *channels) const {
getActualRGBCW(&channels[0], &channels[1], &channels[2], &channels[3], &channels[4]);
}
void getChannelsRaw(uint8_t *channels) {
void getChannelsRaw(uint8_t *channels) const {
channels[0] = _r;
channels[1] = _g;
channels[2] = _b;
@ -450,24 +462,24 @@ class LightStateClass {
channels[4] = _ww;
}
void getHSB(uint16_t *hue, uint8_t *sat, uint8_t *bri) {
void getHSB(uint16_t *hue, uint8_t *sat, uint8_t *bri) const {
if (hue) { *hue = _hue; }
if (sat) { *sat = _sat; }
if (bri) { *bri = _briRGB; }
}
// getBri() is guaranteed to give the same result as setBri() - no rounding errors.
uint8_t getBri(void) {
uint8_t getBri(void) const {
// return the max of _briCT and _briRGB
return (_briRGB >= _briCT) ? _briRGB : _briCT;
}
// get the white Brightness
inline uint8_t getBriCT() {
inline uint8_t getBriCT(void) const {
return _briCT;
}
inline uint8_t getBriCTOrig() {
inline uint8_t getBriCTOrig(void) const {
return _briCT_orig;
}
@ -481,7 +493,7 @@ class LightStateClass {
return dimmer;
}
uint8_t getDimmer(uint32_t mode = 0) {
uint8_t getDimmer(uint32_t mode = 0) const {
uint8_t bri;
switch (mode) {
case 1:
@ -497,12 +509,12 @@ class LightStateClass {
return BriToDimmer(bri);
}
inline uint16_t getCT() const {
inline uint16_t getCT(void) const {
return _ct; // 153..500, or CT_MIN..CT_MAX
}
// get current color in XY format
void getXY(float *x, float *y) {
void getXY(float *x, float *y) const {
RgbToXy(_r, _g, _b, x, y);
}
@ -532,11 +544,11 @@ class LightStateClass {
return prev_bri;
}
inline uint8_t getBriRGB() {
inline uint8_t getBriRGB(void) const {
return _briRGB;
}
inline uint8_t getBriRGBOrig() {
inline uint8_t getBriRGBOrig(void) const {
return _briRGB_orig;
}

View File

@ -568,10 +568,27 @@ bool HueActive(uint8_t device) {
return '$' != *SettingsText(SET_FRIENDLYNAME1 +device -1);
}
/*********************************************************************************\
* HueLightStatus2Generic
*
* Adds specific information for a newly discovered device
\*********************************************************************************/
void HueLightStatus2Generic(String *response, const char * name, const char * modelid, const char * manuf, const char * uniqueid) {
// //=HUE_LIGHTS_STATUS_JSON2
// ",\"type\":\"Extended color light\","
// "\"name\":\"%s\","
// "\"modelid\":\"%s\","
// "\"manufacturername\":\"%s\","
// "\"uniqueid\":\"%s\"}"
UnishoxStrings msg(HUE_LIGHTS);
char * buf = ext_snprintf_malloc_P(msg[HUE_LIGHTS_STATUS_JSON2], EscapeJSONString(name).c_str(), EscapeJSONString(modelid).c_str(), EscapeJSONString(manuf).c_str(), uniqueid);
*response += buf;
free(buf);
}
void HueLightStatus2(uint8_t device, String *response)
{
const size_t buf_size = 300;
char * buf = (char*) malloc(buf_size);
const size_t max_name_len = 32;
char fname[max_name_len + 1];
@ -588,14 +605,8 @@ void HueLightStatus2(uint8_t device, String *response)
}
fname[fname_len] = 0x00;
}
UnishoxStrings msg(HUE_LIGHTS);
snprintf_P(buf, buf_size, msg[HUE_LIGHTS_STATUS_JSON2],
EscapeJSONString(fname).c_str(),
EscapeJSONString(Settings->user_template_name).c_str(),
PSTR("Tasmota"),
GetHueDeviceId(device).c_str());
*response += buf;
free(buf);
HueLightStatus2Generic(response, fname, Settings->user_template_name, PSTR("Tasmota"), GetHueDeviceId(device).c_str());
}
#endif // USE_LIGHT

View File

@ -91,9 +91,6 @@ void HueLightStatus1Zigbee(uint16_t shortaddr, uint8_t local_light_subtype, Stri
void HueLightStatus2Zigbee(uint16_t shortaddr, String *response)
{
const size_t buf_size = 300;
char * buf = (char*) malloc(buf_size);
const Z_Device & device = zigbee_devices.findShortAddr(shortaddr);
const char * friendlyName = device.friendlyName;
const char * modelId = device.modelId;
@ -101,15 +98,10 @@ void HueLightStatus2Zigbee(uint16_t shortaddr, String *response)
char shortaddrname[8];
snprintf_P(shortaddrname, sizeof(shortaddrname), PSTR("0x%04X"), shortaddr);
UnishoxStrings msg(HUE_LIGHTS);
snprintf_P(buf, buf_size, msg[HUE_LIGHTS_STATUS_JSON2],
(friendlyName) ? EscapeJSONString(friendlyName).c_str() : shortaddrname,
(modelId) ? EscapeJSONString(modelId).c_str() : PSTR("Unknown"),
(manufacturerId) ? EscapeJSONString(manufacturerId).c_str() : PSTR("Tasmota"),
HueLightStatus2Generic(response, (friendlyName) ? friendlyName : shortaddrname,
(modelId) ? modelId : PSTR("Unknown"),
(manufacturerId) ? manufacturerId : PSTR("Tasmota"),
GetHueDeviceId(shortaddr).c_str());
*response += buf;
free(buf);
}
int32_t ZigbeeHueStatus(String * response, uint16_t shortaddr) {

View File

@ -0,0 +1,211 @@
/*
xdrv_52_3_berry_light_state.ino - Berry scripting language, native fucnctions
Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Mappgin from internal light and a generic `light_state` Berry class
#ifdef USE_BERRY
#ifdef USE_LIGHT
#include "berry.h"
void* ls_init(int32_t channels) {
LightStateClass * l = new LightStateClass();
l->setSubType(channels);
return (LightStateClass*)l;
}
int32_t ls_r(void* p) {
LightStateClass * l = (LightStateClass *) p;
uint8_t r;
l->getActualRGBCW(&r, NULL, NULL, NULL, NULL);
return r;
}
int32_t ls_g(void* p) {
LightStateClass * l = (LightStateClass *) p;
uint8_t g;
l->getActualRGBCW(NULL, &g, NULL, NULL, NULL);
return g;
}
int32_t ls_b(void* p) {
LightStateClass * l = (LightStateClass *) p;
uint8_t b;
l->getActualRGBCW(NULL, NULL, &b, NULL, NULL);
return b;
}
float ls_x(void* p) {
LightStateClass * l = (LightStateClass *) p;
float x;
l->getXY(&x, NULL);
return x;
}
float ls_y(void* p) {
LightStateClass * l = (LightStateClass *) p;
float y;
l->getXY(NULL, &y);
return y;
}
int32_t ls_hue(void* p) {
LightStateClass * l = (LightStateClass *) p;
uint16_t hue;
l->getHSB(&hue, NULL, NULL);
return hue;
}
int32_t ls_sat(void* p) {
LightStateClass * l = (LightStateClass *) p;
uint8_t sat;
l->getHSB(NULL, &sat, NULL);
return sat;
}
int32_t ls_bri(void* p) {
LightStateClass * l = (LightStateClass *) p;
return l->getBri();
}
void ls_set_rgb(void* p, int32_t r, int32_t g, int32_t b) {
LightStateClass * l = (LightStateClass *) p;
l->setRGB(r, g, b, false);
}
void ls_set_huesat(void* p, int32_t hue, int32_t sat) {
LightStateClass * l = (LightStateClass *) p;
l->setHS(hue, sat);
}
int32_t ls_get_power(void* p) {
LightStateClass * l = (LightStateClass *) p;
return l->getPower();
}
void ls_set_xy(void* p, float x, float y) {
LightStateClass * l = (LightStateClass *) p;
uint8_t rr, gg, bb;
uint16_t hue;
uint8_t sat;
XyToRgb(x, y, &rr, &gg, &bb);
l->setRGB(rr, gg, bb, false);
}
void ls_set_power(void* p, int32_t pow) {
LightStateClass * l = (LightStateClass *) p;
l->setPower(pow);
}
void ls_set_mode_rgb(void* p) {
LightStateClass * l = (LightStateClass *) p;
l->setColorMode(LCM_RGB);
}
void ls_set_mode_ct(void* p) {
LightStateClass * l = (LightStateClass *) p;
l->setColorMode(LCM_CT);
}
int32_t ls_mode_rgb(void* p) {
LightStateClass * l = (LightStateClass *) p;
return (l->getColorMode() & LCM_RGB) ? 1 : 0;
}
int32_t ls_mode_ct(void* p) {
LightStateClass * l = (LightStateClass *) p;
return (l->getColorMode() & LCM_CT) ? 1 : 0;
}
void ls_set_ct(void* p, int32_t ct) {
LightStateClass * l = (LightStateClass *) p;
l->setCT(ct);
l->setColorMode(LCM_CT);
}
int32_t ls_ct(void* p) {
LightStateClass * l = (LightStateClass *) p;
return l->getCT();
}
// Gamma functions
int32_t ls_gamma8(int32_t val) {
return ledGamma(val);
}
int32_t ls_gamma10(int32_t val) {
return ledGamma10_10(val);
}
int32_t ls_rev_gamma10(int32_t val) {
return ledGammaReverse(val);
}
// get returning a complete map, similar to `light.get()`
extern "C" int light_state_get(bvm *vm) {
be_getmember(vm, 1, "_p");
LightStateClass * l = (LightStateClass *) be_tocomptr(vm, -1);
be_newobject(vm, "map");
uint32_t sub_type = l->getSubType();
char s_rgb[8] = {0}; // RGB raw levels string
uint8_t r, g, b, cw, ww;
uint16_t hue;
uint8_t sat;
uint8_t briRGB, briCT;
l->getActualRGBCW(&r, &g, &b, &cw, &ww);
l->getHSB(&hue, &sat, &briRGB);
briCT = l->getBriCT();
bool mode_rgb = l->getColorMode() & LCM_RGB;
bool mode_ct = !mode_rgb;
// bri
be_map_insert_int(vm, "bri", l->getBri());
// color_mode
be_map_insert_bool(vm, "mode_rgb", ls_mode_rgb(l));
if (sub_type >= 4) {
be_map_insert_bool(vm, "mode_ct", ls_mode_ct(l));
}
// RGB
if (sub_type >= 3 && mode_rgb) {
snprintf(s_rgb, sizeof(s_rgb), PSTR("%02X%02X%02X"), r, g, b);
be_map_insert_str(vm, "rgb", s_rgb);
be_map_insert_int(vm, "hue", hue);
be_map_insert_int(vm, "sat", sat);
}
// CT when 2 white channels
if ((sub_type == 2 || sub_type == 5) && mode_ct) {
be_map_insert_int(vm, "ct", l->getCT());
}
uint8_t channels[LST_MAX] = {0};
switch (sub_type) {
case 1:
channels[0] = briRGB;
break;
case 2:
channels[0] = cw;
channels[1] = ww;
break;
case 3:
case 4:
case 5:
channels[0] = r;
channels[1] = g;
channels[2] = b;
channels[3] = cw;
channels[4] = ww;
break;
}
be_map_insert_list_uint8(vm, "channels", channels, sub_type);
be_pop(vm, 1);
be_return(vm);
}
#endif // USE_LIGHT
#endif // USE_BERRY