mirror of https://github.com/arendst/Tasmota.git
Merge pull request #14703 from s-hadinger/berry_light_state
Berry add light_state class
This commit is contained in:
commit
51ef4078b2
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
);
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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]}")
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue