Berry virtual Alexa Hue device (#14833)

* Berry virtual Alexa Hue device

* Fix compilation
This commit is contained in:
s-hadinger 2022-02-13 22:59:43 +01:00 committed by GitHub
parent 7165258602
commit 945682aa78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 2440 additions and 1130 deletions

View File

@ -41,6 +41,8 @@ be_extern_native_module(webserver);
be_extern_native_module(flash);
be_extern_native_module(path);
be_extern_native_module(unishox);
be_extern_native_module(hue_ntv);
be_extern_native_module(hue_bridge);
be_extern_native_module(uuid);
be_extern_native_module(animate);
#ifdef USE_LVGL
@ -118,6 +120,10 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_LIGHT
&be_native_module(light),
#endif
#if defined(USE_EMULATION) && defined(USE_EMULATION_HUE)
&be_native_module(hue_ntv),
&be_native_module(hue_bridge),
#endif
&be_native_module(uuid),
#ifdef USE_UNISHOX_COMPRESSION

View File

@ -15,6 +15,7 @@ extern const bcstring be_const_str_BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20
extern const bcstring be_const_str_BRY_X3A_X20argument_X20must_X20be_X20a_X20function;
extern const bcstring be_const_str_BRY_X3A_X20could_X20not_X20save_X20compiled_X20file_X20_X25s_X20_X28_X25s_X29;
extern const bcstring be_const_str_BRY_X3A_X20failed_X20to_X20load_X20_persist_X2Ejson;
extern const bcstring be_const_str_BRY_X3A_X20invalid_X20hue_X20payload_X3A_X20;
extern const bcstring be_const_str_BRY_X3A_X20method_X20not_X20allowed_X2C_X20use_X20a_X20closure_X20like_X20_X27_X2F_X20args_X20_X2D_X3E_X20obj_X2Efunc_X28args_X29_X27;
extern const bcstring be_const_str_BUTTON_CONFIGURATION;
extern const bcstring be_const_str_CFG_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s;
@ -64,6 +65,7 @@ extern const bcstring be_const_str_OpusDecoder;
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_RELAY;
extern const bcstring be_const_str_RES_OK;
extern const bcstring be_const_str_RGB;
extern const bcstring be_const_str_RGBCT;
@ -100,6 +102,7 @@ extern const bcstring be_const_str_Tasmota;
extern const bcstring be_const_str_Tele;
extern const bcstring be_const_str_Timer;
extern const bcstring be_const_str_True;
extern const bcstring be_const_str_Unknown;
extern const bcstring be_const_str_Unknown_X20command;
extern const bcstring be_const_str_WS2812;
extern const bcstring be_const_str_WS2812_GRB;
@ -109,6 +112,8 @@ extern const bcstring be_const_str__X0A;
extern const bcstring be_const_str__X20;
extern const bcstring be_const_str__X21_X3D;
extern const bcstring be_const_str__X21_X3D_X3D;
extern const bcstring be_const_str__X22;
extern const bcstring be_const_str__X22_X3A;
extern const bcstring be_const_str__X23;
extern const bcstring be_const_str__X23autoexec_X2Ebat;
extern const bcstring be_const_str__X23autoexec_X2Ebe;
@ -142,6 +147,8 @@ extern const bcstring be_const_str__X2F;
extern const bcstring be_const_str__X2F_X2Eautoconf;
extern const bcstring be_const_str__X2F_X3Frst_X3D;
extern const bcstring be_const_str__X2Fac;
extern const bcstring be_const_str__X2Flights_X2F;
extern const bcstring be_const_str__X2Fstate_X2F;
extern const bcstring be_const_str__X3A;
extern const bcstring be_const_str__X3C;
extern const bcstring be_const_str__X3C_X2Fform_X3E_X3C_X2Fp_X3E;
@ -226,6 +233,7 @@ extern const bcstring be_const_str_add_event_cb;
extern const bcstring be_const_str_add_fast_loop;
extern const bcstring be_const_str_add_handler;
extern const bcstring be_const_str_add_header;
extern const bcstring be_const_str_add_light;
extern const bcstring be_const_str_add_rule;
extern const bcstring be_const_str_addr;
extern const bcstring be_const_str_allocated;
@ -324,6 +332,7 @@ extern const bcstring be_const_str_counters;
extern const bcstring be_const_str_create_custom_widget;
extern const bcstring be_const_str_create_matrix;
extern const bcstring be_const_str_create_segment;
extern const bcstring be_const_str_ct;
extern const bcstring be_const_str_ctor;
extern const bcstring be_const_str_ctypes_bytes;
extern const bcstring be_const_str_ctypes_bytes_dyn;
@ -347,6 +356,7 @@ extern const bcstring be_const_str_digital_read;
extern const bcstring be_const_str_digital_write;
extern const bcstring be_const_str_dimmer;
extern const bcstring be_const_str_dirty;
extern const bcstring be_const_str_discover;
extern const bcstring be_const_str_display;
extern const bcstring be_const_str_display_X2Eini;
extern const bcstring be_const_str_do;
@ -406,6 +416,8 @@ extern const bcstring be_const_str_from_to;
extern const bcstring be_const_str_fromb64;
extern const bcstring be_const_str_fromptr;
extern const bcstring be_const_str_fromstring;
extern const bcstring be_const_str_full_state;
extern const bcstring be_const_str_full_status;
extern const bcstring be_const_str_function;
extern const bcstring be_const_str_gamma;
extern const bcstring be_const_str_gamma10;
@ -451,6 +463,7 @@ extern const bcstring be_const_str_geti;
extern const bcstring be_const_str_global;
extern const bcstring be_const_str_gpio;
extern const bcstring be_const_str_group_def;
extern const bcstring be_const_str_groups;
extern const bcstring be_const_str_h;
extern const bcstring be_const_str_has;
extern const bcstring be_const_str_has_X20already_X20an_X20event_X20callback;
@ -461,8 +474,12 @@ extern const bcstring be_const_str_hour;
extern const bcstring be_const_str_hs2rgb;
extern const bcstring be_const_str_https_X3A_X2F_X2Fraw_X2Egithubusercontent_X2Ecom_X2Ftasmota_X2Fautoconf_X2Fmain_X2F_X25s_X2F_X25s_X2Eautoconf;
extern const bcstring be_const_str_https_X3A_X2F_X2Fraw_X2Egithubusercontent_X2Ecom_X2Ftasmota_X2Fautoconf_X2Fmain_X2F_X25s_manifest_X2Ejson;
extern const bcstring be_const_str_hue;
extern const bcstring be_const_str_hue_ntv;
extern const bcstring be_const_str_hue_status;
extern const bcstring be_const_str_i2c_enabled;
extern const bcstring be_const_str_id;
extern const bcstring be_const_str_id_X20must_X20be_X20of_X20type_X20_X27int_X27;
extern const bcstring be_const_str_if;
extern const bcstring be_const_str_imax;
extern const bcstring be_const_str_imin;
@ -507,7 +524,9 @@ 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_X20must_X20be_X20of_X20class_X20_X27light_state_X27;
extern const bcstring be_const_str_light_state;
extern const bcstring be_const_str_lights;
extern const bcstring be_const_str_line_dsc;
extern const bcstring be_const_str_list;
extern const bcstring be_const_str_list_handlers;
@ -541,6 +560,7 @@ extern const bcstring be_const_str_lv_wifi_bars;
extern const bcstring be_const_str_lv_wifi_bars_icon;
extern const bcstring be_const_str_lvgl_event_dispatch;
extern const bcstring be_const_str_make_cb;
extern const bcstring be_const_str_manuf;
extern const bcstring be_const_str_map;
extern const bcstring be_const_str_math;
extern const bcstring be_const_str_matrix;
@ -550,6 +570,8 @@ extern const bcstring be_const_str_memory;
extern const bcstring be_const_str_millis;
extern const bcstring be_const_str_min;
extern const bcstring be_const_str_minute;
extern const bcstring be_const_str_missing_X20name;
extern const bcstring be_const_str_model;
extern const bcstring be_const_str_module;
extern const bcstring be_const_str_month;
extern const bcstring be_const_str_montserrat_font;
@ -626,6 +648,7 @@ extern const bcstring be_const_str_remote_port;
extern const bcstring be_const_str_remove;
extern const bcstring be_const_str_remove_cmd;
extern const bcstring be_const_str_remove_driver;
extern const bcstring be_const_str_remove_light;
extern const bcstring be_const_str_remove_rule;
extern const bcstring be_const_str_remove_timer;
extern const bcstring be_const_str_reset;
@ -652,6 +675,7 @@ extern const bcstring be_const_str_run;
extern const bcstring be_const_str_run_bat;
extern const bcstring be_const_str_run_deferred;
extern const bcstring be_const_str_running;
extern const bcstring be_const_str_sat;
extern const bcstring be_const_str_save;
extern const bcstring be_const_str_save_before_restart;
extern const bcstring be_const_str_scale_uint;
@ -678,6 +702,7 @@ 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_hue16sat;
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;
@ -690,6 +715,7 @@ 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_reachable;
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;
@ -714,6 +740,7 @@ extern const bcstring be_const_str_shared_key;
extern const bcstring be_const_str_show;
extern const bcstring be_const_str_signal_arcs;
extern const bcstring be_const_str_signal_bars;
extern const bcstring be_const_str_signal_change;
extern const bcstring be_const_str_sin;
extern const bcstring be_const_str_sinh;
extern const bcstring be_const_str_size;
@ -732,6 +759,7 @@ extern const bcstring be_const_str_strftime;
extern const bcstring be_const_str_string;
extern const bcstring be_const_str_strip;
extern const bcstring be_const_str_strptime;
extern const bcstring be_const_str_success;
extern const bcstring be_const_str_super;
extern const bcstring be_const_str_sys;
extern const bcstring be_const_str_tag;
@ -826,6 +854,7 @@ extern const bcstring be_const_str_write_file;
extern const bcstring be_const_str_write_gpio;
extern const bcstring be_const_str_x;
extern const bcstring be_const_str_x1;
extern const bcstring be_const_str_xy;
extern const bcstring be_const_str_y;
extern const bcstring be_const_str_y1;
extern const bcstring be_const_str_year;

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +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(set_bri, 8), be_const_ctype_func(ls_set_bri) },
{ be_const_key(member, 5), be_const_func(light_state_member) },
{ 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_reachable, 16), be_const_ctype_func(ls_set_reachable) },
{ be_const_key(CT, -1), be_const_int(2) },
{ be_const_key(set_ct, -1), be_const_ctype_func(ls_set_ct) },
{ be_const_key(reverse_gamma10, 13), be_const_ctype_func(ls_rev_gamma10) },
{ be_const_key(set_mode_ct, -1), be_const_ctype_func(ls_set_mode_ct) },
{ be_const_key(RGBCT, -1), be_const_int(5) },
{ be_const_key(set_huesat, -1), be_const_ctype_func(ls_set_huesat) },
{ be_const_key(RELAY, 4), be_const_int(0) },
{ be_const_key(gamma10, 0), be_const_ctype_func(ls_gamma10) },
{ be_const_key(get, 22), be_const_func(light_state_get) },
{ be_const_key(gamma8, -1), be_const_ctype_func(ls_gamma8) },
{ be_const_key(signal_change, 9), be_const_ctype_func(ls_signal_change) },
{ be_const_key(set_rgb, -1), be_const_ctype_func(ls_set_rgb) },
{ be_const_key(set_mode_rgb, 18), be_const_ctype_func(ls_set_mode_rgb) },
{ be_const_key(RGBW, -1), be_const_int(4) },
{ be_const_key(init, -1), be_const_ctype_func(ls_init) },
{ be_const_key(DIMMER, 1), be_const_int(1) },
{ be_const_key(RGB, -1), be_const_int(3) },
{ be_const_key(set_power, -1), be_const_ctype_func(ls_set_power) },
{ be_const_key(set_hue16sat, -1), be_const_ctype_func(ls_set_hue16sat) },
{ be_const_key(set_xy, 12), be_const_ctype_func(ls_set_xy) },
};
static be_define_const_map(
be_class_light_state_map,
19
24
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -0,0 +1,18 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libhue_ntv_map) {
{ be_const_key(full_state, -1), be_const_ctype_func(be_hue_light_full_state) },
{ be_const_key(light_state, -1), be_const_ctype_func(be_hue_light_state) },
};
static be_define_const_map(
m_libhue_ntv_map,
2
);
static be_define_const_module(
m_libhue_ntv,
"hue_ntv"
);
BE_EXPORT_VARIABLE be_define_const_native_module(hue_ntv);

View File

@ -0,0 +1,667 @@
/********************************************************************
* Berry `import hue_bridge`
*
*******************************************************************/
#include "be_constobj.h"
#if defined(USE_EMULATION) && defined(USE_EMULATION_HUE)
/********************************************************************
** Solidified function: cmd
********************************************************************/
be_local_closure(hue_bridge_monad_cmd, /* name */
be_nested_proto(
18, /* nstack */
3, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[31]) { /* constants */
/* K0 */ be_nested_str(json),
/* K1 */ be_nested_str(lights),
/* K2 */ be_nested_str(contains),
/* K3 */ be_nested_str(light),
/* K4 */ be_nested_str(load),
/* K5 */ be_nested_str(tasmota),
/* K6 */ be_nested_str(log),
/* K7 */ be_nested_str(BRY_X3A_X20invalid_X20hue_X20payload_X3A_X20),
/* K8 */ be_const_int(3),
/* K9 */ be_nested_str(on),
/* K10 */ be_nested_str(set_power),
/* K11 */ be_nested_str(xy),
/* K12 */ be_const_int(0),
/* K13 */ be_const_int(1),
/* K14 */ be_nested_str(set_xy),
/* K15 */ be_nested_str(hue),
/* K16 */ be_nested_str(sat),
/* K17 */ be_nested_str(type),
/* K18 */ be_nested_str(set_hue16sat),
/* K19 */ be_nested_str(ct),
/* K20 */ be_nested_str(set_ct),
/* K21 */ be_nested_str(bri),
/* K22 */ be_nested_str(set_bri),
/* K23 */ be_nested_str(keys),
/* K24 */ be_nested_str(_X2Flights_X2F),
/* K25 */ be_nested_str(_X2Fstate_X2F),
/* K26 */ be_nested_str(success),
/* K27 */ be_nested_str(push),
/* K28 */ be_nested_str(stop_iteration),
/* K29 */ be_nested_str(signal_change),
/* K30 */ be_nested_str(dump),
}),
&be_const_str_cmd,
&be_const_str_solidified,
( &(const binstruction[167]) { /* code */
0xA40E0000, // 0000 IMPORT R3 K0
0x88100101, // 0001 GETMBR R4 R0 K1
0x8C100902, // 0002 GETMET R4 R4 K2
0x5C180200, // 0003 MOVE R6 R1
0x7C100400, // 0004 CALL R4 2
0x74120000, // 0005 JMPT R4 #0007
0x80000800, // 0006 RET 0
0x88100101, // 0007 GETMBR R4 R0 K1
0x94100801, // 0008 GETIDX R4 R4 R1
0x94100903, // 0009 GETIDX R4 R4 K3
0x60140013, // 000A GETGBL R5 G19
0x7C140000, // 000B CALL R5 0
0x8C180704, // 000C GETMET R6 R3 K4
0x5C200400, // 000D MOVE R8 R2
0x7C180400, // 000E CALL R6 2
0x4C1C0000, // 000F LDNIL R7
0x1C1C0407, // 0010 EQ R7 R2 R7
0x781E0008, // 0011 JMPF R7 #001B
0xB81E0A00, // 0012 GETNGBL R7 K5
0x8C1C0F06, // 0013 GETMET R7 R7 K6
0x60240008, // 0014 GETGBL R9 G8
0x5C280400, // 0015 MOVE R10 R2
0x7C240200, // 0016 CALL R9 1
0x00260E09, // 0017 ADD R9 K7 R9
0x58280008, // 0018 LDCONST R10 K8
0x7C1C0600, // 0019 CALL R7 3
0x80000E00, // 001A RET 0
0x8C1C0D02, // 001B GETMET R7 R6 K2
0x58240009, // 001C LDCONST R9 K9
0x7C1C0400, // 001D CALL R7 2
0x781E0006, // 001E JMPF R7 #0026
0x601C0017, // 001F GETGBL R7 G23
0x94200D09, // 0020 GETIDX R8 R6 K9
0x7C1C0200, // 0021 CALL R7 1
0x98161207, // 0022 SETIDX R5 K9 R7
0x8C20090A, // 0023 GETMET R8 R4 K10
0x5C280E00, // 0024 MOVE R10 R7
0x7C200400, // 0025 CALL R8 2
0x8C1C0D02, // 0026 GETMET R7 R6 K2
0x5824000B, // 0027 LDCONST R9 K11
0x7C1C0400, // 0028 CALL R7 2
0x781E0013, // 0029 JMPF R7 #003E
0x941C0D0B, // 002A GETIDX R7 R6 K11
0x6020000A, // 002B GETGBL R8 G10
0x94240F0C, // 002C GETIDX R9 R7 K12
0x7C200200, // 002D CALL R8 1
0x6024000A, // 002E GETGBL R9 G10
0x94280F0D, // 002F GETIDX R10 R7 K13
0x7C240200, // 0030 CALL R9 1
0x60280012, // 0031 GETGBL R10 G18
0x7C280000, // 0032 CALL R10 0
0x402C1408, // 0033 CONNECT R11 R10 R8
0x402C1409, // 0034 CONNECT R11 R10 R9
0x9816160A, // 0035 SETIDX R5 K11 R10
0x542AFFFF, // 0036 LDINT R10 65536
0x0820100A, // 0037 MUL R8 R8 R10
0x542AFFFF, // 0038 LDINT R10 65536
0x0824120A, // 0039 MUL R9 R9 R10
0x8C28090E, // 003A GETMET R10 R4 K14
0x5C301000, // 003B MOVE R12 R8
0x5C341200, // 003C MOVE R13 R9
0x7C280600, // 003D CALL R10 3
0x501C0000, // 003E LDBOOL R7 0 0
0x8820090F, // 003F GETMBR R8 R4 K15
0x88240910, // 0040 GETMBR R9 R4 K16
0x8C280D02, // 0041 GETMET R10 R6 K2
0x5830000F, // 0042 LDCONST R12 K15
0x7C280400, // 0043 CALL R10 2
0x782A0009, // 0044 JMPF R10 #004F
0x60280009, // 0045 GETGBL R10 G9
0x942C0D0F, // 0046 GETIDX R11 R6 K15
0x7C280200, // 0047 CALL R10 1
0x5C201400, // 0048 MOVE R8 R10
0x98161E08, // 0049 SETIDX R5 K15 R8
0x542AFFFE, // 004A LDINT R10 65535
0x2428100A, // 004B GT R10 R8 R10
0x782A0000, // 004C JMPF R10 #004E
0x5422FFFE, // 004D LDINT R8 65535
0x501C0200, // 004E LDBOOL R7 1 0
0x8C280D02, // 004F GETMET R10 R6 K2
0x58300010, // 0050 LDCONST R12 K16
0x7C280400, // 0051 CALL R10 2
0x782A000C, // 0052 JMPF R10 #0060
0x60280009, // 0053 GETGBL R10 G9
0x942C0D10, // 0054 GETIDX R11 R6 K16
0x7C280200, // 0055 CALL R10 1
0x5C241400, // 0056 MOVE R9 R10
0x98162009, // 0057 SETIDX R5 K16 R9
0x542A00FD, // 0058 LDINT R10 254
0x2828120A, // 0059 GE R10 R9 R10
0x782A0000, // 005A JMPF R10 #005C
0x542600FE, // 005B LDINT R9 255
0x88280911, // 005C GETMBR R10 R4 K17
0x28281508, // 005D GE R10 R10 K8
0x782A0000, // 005E JMPF R10 #0060
0x501C0200, // 005F LDBOOL R7 1 0
0x781E0003, // 0060 JMPF R7 #0065
0x8C280912, // 0061 GETMET R10 R4 K18
0x5C301000, // 0062 MOVE R12 R8
0x5C341200, // 0063 MOVE R13 R9
0x7C280600, // 0064 CALL R10 3
0x8C280D02, // 0065 GETMET R10 R6 K2
0x58300013, // 0066 LDCONST R12 K19
0x7C280400, // 0067 CALL R10 2
0x782A0006, // 0068 JMPF R10 #0070
0x60280009, // 0069 GETGBL R10 G9
0x942C0D13, // 006A GETIDX R11 R6 K19
0x7C280200, // 006B CALL R10 1
0x9816260A, // 006C SETIDX R5 K19 R10
0x8C2C0914, // 006D GETMET R11 R4 K20
0x5C341400, // 006E MOVE R13 R10
0x7C2C0400, // 006F CALL R11 2
0x8C280D02, // 0070 GETMET R10 R6 K2
0x58300015, // 0071 LDCONST R12 K21
0x7C280400, // 0072 CALL R10 2
0x782A000A, // 0073 JMPF R10 #007F
0x60280009, // 0074 GETGBL R10 G9
0x942C0D15, // 0075 GETIDX R11 R6 K21
0x7C280200, // 0076 CALL R10 1
0x98162A0A, // 0077 SETIDX R5 K21 R10
0x542E00FD, // 0078 LDINT R11 254
0x282C140B, // 0079 GE R11 R10 R11
0x782E0000, // 007A JMPF R11 #007C
0x542A00FE, // 007B LDINT R10 255
0x8C2C0916, // 007C GETMET R11 R4 K22
0x5C341400, // 007D MOVE R13 R10
0x7C2C0400, // 007E CALL R11 2
0x60280012, // 007F GETGBL R10 G18
0x7C280000, // 0080 CALL R10 0
0x602C0010, // 0081 GETGBL R11 G16
0x8C300B17, // 0082 GETMET R12 R5 K23
0x7C300200, // 0083 CALL R12 1
0x7C2C0200, // 0084 CALL R11 1
0xA8020012, // 0085 EXBLK 0 #0099
0x5C301600, // 0086 MOVE R12 R11
0x7C300000, // 0087 CALL R12 0
0x60340008, // 0088 GETGBL R13 G8
0x5C380200, // 0089 MOVE R14 R1
0x7C340200, // 008A CALL R13 1
0x0036300D, // 008B ADD R13 K24 R13
0x00341B19, // 008C ADD R13 R13 K25
0x00341A0C, // 008D ADD R13 R13 R12
0x60380013, // 008E GETGBL R14 G19
0x7C380000, // 008F CALL R14 0
0x603C0013, // 0090 GETGBL R15 G19
0x7C3C0000, // 0091 CALL R15 0
0x94400A0C, // 0092 GETIDX R16 R5 R12
0x983C1A10, // 0093 SETIDX R15 R13 R16
0x983A340F, // 0094 SETIDX R14 K26 R15
0x8C3C151B, // 0095 GETMET R15 R10 K27
0x5C441C00, // 0096 MOVE R17 R14
0x7C3C0400, // 0097 CALL R15 2
0x7001FFEC, // 0098 JMP #0086
0x582C001C, // 0099 LDCONST R11 K28
0xAC2C0200, // 009A CATCH R11 1 0
0xB0080000, // 009B RAISE 2 R0 R0
0x602C000C, // 009C GETGBL R11 G12
0x5C301400, // 009D MOVE R12 R10
0x7C2C0200, // 009E CALL R11 1
0x242C170C, // 009F GT R11 R11 K12
0x782E0001, // 00A0 JMPF R11 #00A3
0x8C2C091D, // 00A1 GETMET R11 R4 K29
0x7C2C0200, // 00A2 CALL R11 1
0x8C2C071E, // 00A3 GETMET R11 R3 K30
0x5C341400, // 00A4 MOVE R13 R10
0x7C2C0400, // 00A5 CALL R11 2
0x80041600, // 00A6 RET 1 R11
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: remove_light
********************************************************************/
be_local_closure(hue_bridge_monad_remove_light, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(lights),
/* K1 */ be_nested_str(remove),
}),
&be_const_str_remove_light,
&be_const_str_solidified,
( &(const binstruction[ 5]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x8C080501, // 0001 GETMET R2 R2 K1
0x5C100200, // 0002 MOVE R4 R1
0x7C080400, // 0003 CALL R2 2
0x80000000, // 0004 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: groups
********************************************************************/
be_local_closure(hue_bridge_monad_groups, /* name */
be_nested_proto(
8, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 8]) { /* constants */
/* K0 */ be_nested_str(lights),
/* K1 */ be_nested_str(keys),
/* K2 */ be_nested_str(push),
/* K3 */ be_nested_str(_X22),
/* K4 */ be_nested_str(stop_iteration),
/* K5 */ be_const_int(0),
/* K6 */ be_nested_str(concat),
/* K7 */ be_nested_str(_X2C),
}),
&be_const_str_groups,
&be_const_str_solidified,
( &(const binstruction[31]) { /* code */
0x60040012, // 0000 GETGBL R1 G18
0x7C040000, // 0001 CALL R1 0
0x60080010, // 0002 GETGBL R2 G16
0x880C0100, // 0003 GETMBR R3 R0 K0
0x8C0C0701, // 0004 GETMET R3 R3 K1
0x7C0C0200, // 0005 CALL R3 1
0x7C080200, // 0006 CALL R2 1
0xA8020009, // 0007 EXBLK 0 #0012
0x5C0C0400, // 0008 MOVE R3 R2
0x7C0C0000, // 0009 CALL R3 0
0x8C100302, // 000A GETMET R4 R1 K2
0x60180008, // 000B GETGBL R6 G8
0x5C1C0600, // 000C MOVE R7 R3
0x7C180200, // 000D CALL R6 1
0x001A0606, // 000E ADD R6 K3 R6
0x00180D03, // 000F ADD R6 R6 K3
0x7C100400, // 0010 CALL R4 2
0x7001FFF5, // 0011 JMP #0008
0x58080004, // 0012 LDCONST R2 K4
0xAC080200, // 0013 CATCH R2 1 0
0xB0080000, // 0014 RAISE 2 R0 R0
0x6008000C, // 0015 GETGBL R2 G12
0x5C0C0200, // 0016 MOVE R3 R1
0x7C080200, // 0017 CALL R2 1
0x24080505, // 0018 GT R2 R2 K5
0x780A0003, // 0019 JMPF R2 #001E
0x8C080306, // 001A GETMET R2 R1 K6
0x58100007, // 001B LDCONST R4 K7
0x7C080400, // 001C CALL R2 2
0x80040400, // 001D RET 1 R2
0x80000000, // 001E RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: hue_status
********************************************************************/
be_local_closure(hue_bridge_monad_hue_status, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_str(hue_ntv),
/* K1 */ be_nested_str(lights),
/* K2 */ be_nested_str(contains),
/* K3 */ be_nested_str(light_state),
/* K4 */ be_nested_str(light),
}),
&be_const_str_hue_status,
&be_const_str_solidified,
( &(const binstruction[13]) { /* code */
0xA40A0000, // 0000 IMPORT R2 K0
0x880C0101, // 0001 GETMBR R3 R0 K1
0x8C0C0702, // 0002 GETMET R3 R3 K2
0x5C140200, // 0003 MOVE R5 R1
0x7C0C0400, // 0004 CALL R3 2
0x780E0005, // 0005 JMPF R3 #000C
0x8C0C0503, // 0006 GETMET R3 R2 K3
0x88140101, // 0007 GETMBR R5 R0 K1
0x94140A01, // 0008 GETIDX R5 R5 R1
0x94140B04, // 0009 GETIDX R5 R5 K4
0x7C0C0400, // 000A CALL R3 2
0x80040600, // 000B RET 1 R3
0x80000000, // 000C RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: add_light
********************************************************************/
be_local_closure(hue_bridge_monad_add_light, /* name */
be_nested_proto(
10, /* nstack */
6, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[14]) { /* constants */
/* K0 */ be_nested_str(int),
/* K1 */ be_nested_str(value_error),
/* K2 */ be_nested_str(id_X20must_X20be_X20of_X20type_X20_X27int_X27),
/* K3 */ be_nested_str(light_state),
/* K4 */ be_nested_str(light_X20must_X20be_X20of_X20class_X20_X27light_state_X27),
/* K5 */ be_const_int(0),
/* K6 */ be_nested_str(missing_X20name),
/* K7 */ be_nested_str(Unknown),
/* K8 */ be_nested_str(Tasmota),
/* K9 */ be_nested_str(lights),
/* K10 */ be_nested_str(light),
/* K11 */ be_nested_str(name),
/* K12 */ be_nested_str(model),
/* K13 */ be_nested_str(manuf),
}),
&be_const_str_add_light,
&be_const_str_solidified,
( &(const binstruction[43]) { /* code */
0x60180004, // 0000 GETGBL R6 G4
0x5C1C0200, // 0001 MOVE R7 R1
0x7C180200, // 0002 CALL R6 1
0x20180D00, // 0003 NE R6 R6 K0
0x781A0000, // 0004 JMPF R6 #0006
0xB0060302, // 0005 RAISE 1 K1 K2
0x6018000F, // 0006 GETGBL R6 G15
0x5C1C0400, // 0007 MOVE R7 R2
0xB8220600, // 0008 GETNGBL R8 K3
0x7C180400, // 0009 CALL R6 2
0x741A0000, // 000A JMPT R6 #000C
0xB0060304, // 000B RAISE 1 K1 K4
0x60180008, // 000C GETGBL R6 G8
0x5C1C0600, // 000D MOVE R7 R3
0x7C180200, // 000E CALL R6 1
0x5C0C0C00, // 000F MOVE R3 R6
0x6018000C, // 0010 GETGBL R6 G12
0x5C1C0600, // 0011 MOVE R7 R3
0x7C180200, // 0012 CALL R6 1
0x1C180D05, // 0013 EQ R6 R6 K5
0x781A0000, // 0014 JMPF R6 #0016
0xB0060306, // 0015 RAISE 1 K1 K6
0x5C180800, // 0016 MOVE R6 R4
0x741A0000, // 0017 JMPT R6 #0019
0x58100007, // 0018 LDCONST R4 K7
0x5C180A00, // 0019 MOVE R6 R5
0x741A0000, // 001A JMPT R6 #001C
0x58140008, // 001B LDCONST R5 K8
0x88180109, // 001C GETMBR R6 R0 K9
0x601C0013, // 001D GETGBL R7 G19
0x7C1C0000, // 001E CALL R7 0
0x981E1402, // 001F SETIDX R7 K10 R2
0x981E1603, // 0020 SETIDX R7 K11 R3
0x60200008, // 0021 GETGBL R8 G8
0x5C240800, // 0022 MOVE R9 R4
0x7C200200, // 0023 CALL R8 1
0x981E1808, // 0024 SETIDX R7 K12 R8
0x60200008, // 0025 GETGBL R8 G8
0x5C240A00, // 0026 MOVE R9 R5
0x7C200200, // 0027 CALL R8 1
0x981E1A08, // 0028 SETIDX R7 K13 R8
0x98180207, // 0029 SETIDX R6 R1 R7
0x80000000, // 002A RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(hue_bridge_monad_init, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str(lights),
}),
&be_const_str_init,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x60040013, // 0000 GETGBL R1 G19
0x7C040000, // 0001 CALL R1 0
0x90020001, // 0002 SETMBR R0 K0 R1
0x80000000, // 0003 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: discover
********************************************************************/
be_local_closure(hue_bridge_monad_discover, /* name */
be_nested_proto(
11, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[13]) { /* constants */
/* K0 */ be_nested_str(hue_ntv),
/* K1 */ be_nested_str(json),
/* K2 */ be_nested_str(string),
/* K3 */ be_nested_str(lights),
/* K4 */ be_nested_str(keys),
/* K5 */ be_nested_str(full_status),
/* K6 */ be_nested_str(_X22),
/* K7 */ be_nested_str(_X22_X3A),
/* K8 */ be_nested_str(push),
/* K9 */ be_nested_str(stop_iteration),
/* K10 */ be_const_int(0),
/* K11 */ be_nested_str(concat),
/* K12 */ be_nested_str(_X2C),
}),
&be_const_str_discover,
&be_const_str_solidified,
( &(const binstruction[40]) { /* code */
0xA4060000, // 0000 IMPORT R1 K0
0xA40A0200, // 0001 IMPORT R2 K1
0xA40E0400, // 0002 IMPORT R3 K2
0x60100012, // 0003 GETGBL R4 G18
0x7C100000, // 0004 CALL R4 0
0x60140010, // 0005 GETGBL R5 G16
0x88180103, // 0006 GETMBR R6 R0 K3
0x8C180D04, // 0007 GETMET R6 R6 K4
0x7C180200, // 0008 CALL R6 1
0x7C140200, // 0009 CALL R5 1
0xA802000F, // 000A EXBLK 0 #001B
0x5C180A00, // 000B MOVE R6 R5
0x7C180000, // 000C CALL R6 0
0x8C1C0105, // 000D GETMET R7 R0 K5
0x5C240C00, // 000E MOVE R9 R6
0x7C1C0400, // 000F CALL R7 2
0x781E0008, // 0010 JMPF R7 #001A
0x60200008, // 0011 GETGBL R8 G8
0x5C240C00, // 0012 MOVE R9 R6
0x7C200200, // 0013 CALL R8 1
0x00220C08, // 0014 ADD R8 K6 R8
0x00201107, // 0015 ADD R8 R8 K7
0x001C1007, // 0016 ADD R7 R8 R7
0x8C200908, // 0017 GETMET R8 R4 K8
0x5C280E00, // 0018 MOVE R10 R7
0x7C200400, // 0019 CALL R8 2
0x7001FFEF, // 001A JMP #000B
0x58140009, // 001B LDCONST R5 K9
0xAC140200, // 001C CATCH R5 1 0
0xB0080000, // 001D RAISE 2 R0 R0
0x6014000C, // 001E GETGBL R5 G12
0x5C180800, // 001F MOVE R6 R4
0x7C140200, // 0020 CALL R5 1
0x24140B0A, // 0021 GT R5 R5 K10
0x78160003, // 0022 JMPF R5 #0027
0x8C14090B, // 0023 GETMET R5 R4 K11
0x581C000C, // 0024 LDCONST R7 K12
0x7C140400, // 0025 CALL R5 2
0x80040A00, // 0026 RET 1 R5
0x80000000, // 0027 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: full_status
********************************************************************/
be_local_closure(hue_bridge_monad_full_status, /* name */
be_nested_proto(
11, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 8]) { /* constants */
/* K0 */ be_nested_str(hue_ntv),
/* K1 */ be_nested_str(lights),
/* K2 */ be_nested_str(contains),
/* K3 */ be_nested_str(full_state),
/* K4 */ be_nested_str(light),
/* K5 */ be_nested_str(name),
/* K6 */ be_nested_str(model),
/* K7 */ be_nested_str(manuf),
}),
&be_const_str_full_status,
&be_const_str_solidified,
( &(const binstruction[17]) { /* code */
0xA40A0000, // 0000 IMPORT R2 K0
0x880C0101, // 0001 GETMBR R3 R0 K1
0x8C0C0702, // 0002 GETMET R3 R3 K2
0x5C140200, // 0003 MOVE R5 R1
0x7C0C0400, // 0004 CALL R3 2
0x780E0009, // 0005 JMPF R3 #0010
0x880C0101, // 0006 GETMBR R3 R0 K1
0x940C0601, // 0007 GETIDX R3 R3 R1
0x8C100503, // 0008 GETMET R4 R2 K3
0x5C180200, // 0009 MOVE R6 R1
0x941C0704, // 000A GETIDX R7 R3 K4
0x94200705, // 000B GETIDX R8 R3 K5
0x94240706, // 000C GETIDX R9 R3 K6
0x94280707, // 000D GETIDX R10 R3 K7
0x7C100C00, // 000E CALL R4 6
0x80040800, // 000F RET 1 R4
0x80000000, // 0010 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: hue_bridge_monad
********************************************************************/
be_local_class(hue_bridge_monad,
1,
NULL,
be_nested_map(9,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key(lights, 1), be_const_var(0) },
{ be_const_key(groups, -1), be_const_closure(hue_bridge_monad_groups_closure) },
{ be_const_key(remove_light, 3), be_const_closure(hue_bridge_monad_remove_light_closure) },
{ be_const_key(discover, -1), be_const_closure(hue_bridge_monad_discover_closure) },
{ be_const_key(hue_status, -1), be_const_closure(hue_bridge_monad_hue_status_closure) },
{ be_const_key(add_light, -1), be_const_closure(hue_bridge_monad_add_light_closure) },
{ be_const_key(cmd, 7), be_const_closure(hue_bridge_monad_cmd_closure) },
{ be_const_key(init, -1), be_const_closure(hue_bridge_monad_init_closure) },
{ be_const_key(full_status, -1), be_const_closure(hue_bridge_monad_full_status_closure) },
})),
be_str_literal("hue_bridge_monad")
);
/********************************************************************
** Solidified function: _anonymous_
********************************************************************/
be_local_closure(hue_bridge__anonymous_, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_const_class(be_class_hue_bridge_monad),
}),
&be_const_str__anonymous_,
&be_const_str_solidified,
( &(const binstruction[ 5]) { /* code */
0x58040000, // 0000 LDCONST R1 K0
0xB4000000, // 0001 CLASS K0
0x5C080200, // 0002 MOVE R2 R1
0x7C080000, // 0003 CALL R2 0
0x80040400, // 0004 RET 1 R2
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified module: hue_bridge
********************************************************************/
be_local_module(hue_bridge,
"hue_bridge",
be_nested_map(1,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key(init, -1), be_const_closure(hue_bridge__anonymous__closure) },
}))
);
BE_EXPORT_VARIABLE be_define_const_native_module(hue_bridge);
/********************************************************************/
#endif // defined(USE_EMULATION) && defined(USE_EMULATION_HUE)

View File

@ -0,0 +1,28 @@
/********************************************************************
* Berry module `hue`
*
* Management of virtual lights for use with Alexa-Hue emulation
*
* To use: `import hue`
*
*
*******************************************************************/
#if defined(USE_EMULATION) && defined(USE_EMULATION_HUE)
#include "be_constobj.h"
#include "be_mapping.h"
extern char* be_hue_light_state(class LightStateClass* l); BE_FUNC_CTYPE_DECLARE(be_hue_light_state, "$", "(light_state)")
extern char* be_hue_light_full_state(int32_t id, class LightStateClass* l, const char* name, const char* model, const char* manuf);
BE_FUNC_CTYPE_DECLARE(be_hue_light_full_state, "$", "i(light_state)s[ss]")
/* @const_object_info_begin
module hue_ntv (scope: global) {
light_state, ctype_func(be_hue_light_state)
full_state, ctype_func(be_hue_light_full_state)
}
@const_object_info_end */
#include "be_fixed_hue_ntv.h"
#endif // defined(USE_EMULATION) && defined(USE_EMULATION_HUE)

View File

@ -14,43 +14,55 @@
#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 void * ls_init(int32_t type); BE_FUNC_CTYPE_DECLARE(ls_init, "+_p", "i")
extern void ls_set_rgb(class LightStateClass* l, int32_t r, int32_t g, int32_t b); BE_FUNC_CTYPE_DECLARE(ls_set_rgb, "", ".iii")
extern void ls_set_huesat(class LightStateClass* l, int32_t hue, int32_t sat); BE_FUNC_CTYPE_DECLARE(ls_set_huesat, "", ".ii")
extern void ls_set_hue16sat(class LightStateClass* l, int32_t hue16, int32_t sat); BE_FUNC_CTYPE_DECLARE(ls_set_hue16sat, "", ".ii")
extern void ls_set_ct(class LightStateClass* l, int32_t ct); BE_FUNC_CTYPE_DECLARE(ls_set_ct, "", ".i")
extern void ls_set_bri(class LightStateClass* l, int32_t bri); BE_FUNC_CTYPE_DECLARE(ls_set_bri, "", ".i")
extern void ls_set_xy(class LightStateClass* l, float x, float y); BE_FUNC_CTYPE_DECLARE(ls_set_xy, "", ".ff")
extern int32_t ls_r(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_r, "i");
extern int32_t ls_g(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_g, "i");
extern int32_t ls_b(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_b, "i");
extern float ls_x(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_x, "f");
extern float ls_y(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_y, "f");
extern int32_t ls_hue(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_hue, "i");
extern int32_t ls_hue16(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_hue16, "i");
extern int32_t ls_sat(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_sat, "i");
extern int32_t ls_bri(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_bri, "i");
extern int32_t ls_ct(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_ct, "i");
extern int32_t ls_type(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_type, "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_mode_rgb(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_mode_rgb, "b");
extern int32_t ls_mode_ct(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_mode_ct, "b");
extern void ls_set_mode_rgb(class LightStateClass* l); BE_FUNC_CTYPE_DECLARE(ls_set_mode_rgb, "", ".");
extern void ls_set_mode_ct(class LightStateClass* l); BE_FUNC_CTYPE_DECLARE(ls_set_mode_ct, "", ".");
extern int32_t ls_get_power(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_get_power, "b");
extern void ls_set_power(class LightStateClass* l, int32_t pow); BE_FUNC_CTYPE_DECLARE(ls_set_power, "", ".b");
extern int32_t ls_reachable(class LightStateClass* p); BE_VAR_CTYPE_DECLARE(ls_reachable, "b");
extern void ls_set_reachable(class LightStateClass* l, int32_t pow); BE_FUNC_CTYPE_DECLARE(ls_set_reachable, "", ".b");
extern void ls_signal_change(void) {} BE_FUNC_CTYPE_DECLARE(ls_signal_change, "", ".");
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")
// moved to constants array
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) },
{ ">hue16", be_ctype(ls_hue16) },
{ ">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) },
{ ">reachable", be_ctype(ls_reachable) },
{ ">sat", be_ctype(ls_sat) },
{ ">type", be_ctype(ls_type) },
{ ">x", be_ctype(ls_x) },
{ ">y", be_ctype(ls_y) },
};
@ -75,6 +87,7 @@ extern "C" void be_load_light_state_class(bvm *vm) {
/* @const_object_info_begin
class be_class_light_state (scope: global, name: light_state) {
RELAY, int(0)
DIMMER, int(1)
CT, int(2)
RGB, int(3)
@ -88,15 +101,20 @@ class be_class_light_state (scope: global, name: light_state) {
set_rgb, ctype_func(ls_set_rgb)
set_huesat, ctype_func(ls_set_huesat)
set_hue16sat, ctype_func(ls_set_hue16sat)
set_xy, ctype_func(ls_set_xy)
set_ct, ctype_func(ls_set_ct)
set_bri, ctype_func(ls_set_bri)
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)
set_reachable, ctype_func(ls_set_reachable)
get, func(light_state_get)
signal_change, ctype_func(ls_signal_change)
gamma8, ctype_func(ls_gamma8)
gamma10, ctype_func(ls_gamma10)
reverse_gamma10, ctype_func(ls_rev_gamma10)

View File

@ -0,0 +1,170 @@
# class containing all registered Alexa/Hue lights
#
# simulates a Hue bridge containing multiple lights
var hue_bridge = module("hue_bridge")
hue_bridge.init = def (m)
class hue_bridge_monad
var lights
def init()
self.lights = {}
end
# add a new light by id
def add_light(id, light, name, model, manuf)
if type(id) != 'int' raise "value_error", "id must be of type 'int'" end
if !isinstance(light, light_state) raise "value_error", "light must be of class 'light_state'" end
name = str(name) # force string type
if size(name) == 0 raise "value_error", "missing name" end
if !model model = "Unknown" end
if !manuf manuf = "Tasmota" end
self.lights[id] = { 'light': light, 'name':name, 'model': str(model), 'manuf':str(manuf) }
light
end
def remove_light(id)
self.lights.remove(id)
end
# return the status of a single light by id
def hue_status(id)
import hue_ntv
if self.lights.contains(id)
return hue_ntv.light_state(self.lights[id]['light'])
end
end
# hue_status takes an id, and return a string with status, or `nil` if not found
def full_status(id)
import hue_ntv
if self.lights.contains(id)
var l = self.lights[id]
return hue_ntv.full_state(id, l['light'], l['name'], l['model'], l['manuf'])
end
end
# discovery of new devices, returns a partial json string, or `nil` if no device
def discover()
import hue_ntv
import json
import string
var fragments = [] # store json elements
for id: self.lights.keys()
var fragment = self.full_status(id)
if fragment
fragment = '"' + str(id) + '":' + fragment;
fragments.push(fragment)
end
end
if size(fragments) > 0
return fragments.concat(",")
end
end
# receive a command from Alexa
def cmd(id, arg)
import json
if !self.lights.contains(id) return end # not our light, ignore
var l = self.lights[id]['light']
var resp = {} # response
# parse input json
# ex: '{"on":true,"bri":117}'
var hue_cmd = json.load(arg)
if arg == nil
tasmota.log("BRY: invalid hue payload: " + str(arg), 3)
return
end
# 'on'
if hue_cmd.contains('on')
var onoff = bool(hue_cmd['on'])
resp['on'] = onoff # ack command
l.set_power(onoff)
end
# handle xy before Hue/Sat
# If the request contains both XY and HS, we wan't to give priority to HS
if hue_cmd.contains('xy')
var xy_arr = hue_cmd['xy']
var x = real(xy_arr[0])
var y = real(xy_arr[1])
resp['xy'] = [x, y]
x *= 65536
y *= 65536
l.set_xy(x, y)
end
# hue
var huesat_changed = false
var hue = l.hue
var sat = l.sat
if hue_cmd.contains('hue')
hue = int(hue_cmd['hue'])
resp['hue'] = hue
if hue > 65535 hue = 65535 end
huesat_changed = true
end
# sat
if hue_cmd.contains('sat')
sat = int(hue_cmd['sat'])
resp['sat'] = sat
if sat >= 254 sat = 255 end
if l.type >= 3
huesat_changed = true
end
end
if huesat_changed
l.set_hue16sat(hue, sat)
end
# ct
if hue_cmd.contains('ct')
var ct = int(hue_cmd['ct'])
resp['ct'] = ct
l.set_ct(ct)
end
# 'bri' after ct/hue to have the right mode
if hue_cmd.contains('bri')
var bri = int(hue_cmd['bri'])
resp['bri'] = bri
if bri >= 254 bri = 255 end # extend bri value if set to max
l.set_bri(bri)
end
# compute response
# Ex: [{"success":{"/lights/10/state/on":true}},{"success":{"/lights/10/state/bri":117}}]
var resp_arr = []
for r: resp.keys()
var path = "/lights/" + str(id) + "/state/" + r
var fragment = {'success': { path: resp[r]}}
resp_arr.push(fragment)
end
if size(resp_arr) > 0 l.signal_change() end
return json.dump(resp_arr)
end
# list group ids, ex: "11,23"
def groups()
var resp = []
for r: self.lights.keys()
resp.push('"' + str(r) + '"')
end
if size(resp) > 0
return resp.concat(',')
end
end
end
return hue_bridge_monad()
end
#hue_bridge = hue_bridge.init(hue_bridge) # for non-solidified
return hue_bridge

View File

@ -0,0 +1,37 @@
# 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)
import hue_ntv
print(l._p)
print(hue_ntv.light_state(l))
print(hue_ntv.full_state(3, l, "aaa", "bbb", "ccc"))
hue_bridge.add_light(10, l, "Synthetic Light", "V1", "DeadParrot")
l1 = light_state(light_state.DIMMER)
hue_bridge.add_light(11, l1, "Synthetic Dimmer", "V1", "DeadParrot")
l2 = light_state(light_state.CT)
# hue_bridge.add_light(12, l2, "Synthetic CT", "V1", "DeadParrot")
hue_bridge.add_light(12, l2, "Synthetic CT")
l5 = light_state(light_state.RGBCT)
hue_bridge.add_light(15, l5, "Synthetic RGBCT")

View File

@ -329,6 +329,7 @@ uint8_t ddp_udp_up = 0;
class LightStateClass {
private:
uint16_t _hue = 0; // 0..359
uint16_t _hue16 = 0; // 0..65535 - high resolution hue necessary for Alexa/Hue integration
uint8_t _sat = 255; // 0..255
uint8_t _briRGB = 255; // 0..255
uint8_t _briRGB_orig = 255; // 0..255
@ -346,6 +347,7 @@ class LightStateClass {
uint8_t _color_mode = LCM_RGB; // RGB by default
bool _power = false; // power indicator, used only in virtual lights, Tasmota tracks power separately
bool _reachable = true; // reachable indicator, used only in vritual lights. Not used in internal light
public:
LightStateClass() {
@ -423,6 +425,14 @@ class LightStateClass {
_power = pow;
}
// reachable accessors, for virtual lights only (has no effect on Tasmota lights)
bool getReachable(void) const {
return _reachable;
}
void setReachable(bool reachable) {
_reachable = reachable;
}
// 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) const {
if (r) { *r = _r; }
@ -643,6 +653,7 @@ class LightStateClass {
_g = g;
_b = b;
_hue = hue;
_hue16 = changeUIntScale(_hue, 0, 360, 0, 65535);
_sat = sat;
#ifdef DEBUG_LIGHT
AddLog(LOG_LEVEL_DEBUG_MORE, "LightStateClass::setRGB RGB raw (%d %d %d) HS (%d %d) bri (%d)", _r, _g, _b, _hue, _sat, _briRGB);
@ -657,6 +668,7 @@ class LightStateClass {
_g = g;
_b = b;
_hue = hue;
_hue16 = changeUIntScale(_hue, 0, 360, 0, 65535);
_sat = sat;
addRGBMode();
#ifdef DEBUG_LIGHT
@ -665,6 +677,17 @@ class LightStateClass {
#endif
}
// version taking Hue over 0..65535 as sent by Zigbee or Hue
void setH16S(uint16_t hue16, uint8_t sat) {
uint16_t hue360 = changeUIntScale(hue16, 0, 65535, 0, 360);
setHS(hue360, sat);
_hue16 = hue16; // keep a higher resolution version in memory
}
uint16_t getHue16(void) const {
return _hue16;
}
// set all 5 channels at once, don't modify the values in ANY way
// Channels are: R G B CW WW
void setChannelsRaw(uint8_t *channels) {
@ -673,7 +696,7 @@ class LightStateClass {
_b = channels[2];
_wc = channels[3];
_ww = channels[4];
}
}
// set all 5 channels at once.
// Channels are: R G B CW WW

View File

@ -32,6 +32,13 @@
#include "UnishoxStrings.h"
#ifdef USE_BERRY
// not sure why they are not infered automatically
bool be_hue_status(String* response, uint32_t device_id);
void be_hue_discovery(String* response, bool* appending);
void be_hue_groups(String* response);
#endif
const char HUE_RESP_MSG_U[] PROGMEM =
//=HUE_RESP_RESPONSE
"HTTP/1.1 200 OK\r\n"
@ -572,8 +579,9 @@ bool HueActive(uint8_t device) {
* HueLightStatus2Generic
*
* Adds specific information for a newly discovered device
* Returns a (char*) pointer that the caller needs to `free()`
\*********************************************************************************/
void HueLightStatus2Generic(String *response, const char * name, const char * modelid, const char * manuf, const char * uniqueid) {
char* HueLightStatus2Generic(const char * name, const char * modelid, const char * manuf, const char * uniqueid) {
// //=HUE_LIGHTS_STATUS_JSON2
// ",\"type\":\"Extended color light\","
// "\"name\":\"%s\","
@ -583,8 +591,7 @@ void HueLightStatus2Generic(String *response, const char * name, const char * mo
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);
return buf;
}
void HueLightStatus2(uint8_t device, String *response)
@ -606,7 +613,9 @@ void HueLightStatus2(uint8_t device, String *response)
fname[fname_len] = 0x00;
}
HueLightStatus2Generic(response, fname, Settings->user_template_name, PSTR("Tasmota"), GetHueDeviceId(device).c_str());
char* buf = HueLightStatus2Generic(fname, Settings->user_template_name, PSTR("Tasmota"), GetHueDeviceId(device).c_str());
*response += buf;
free(buf);
}
#endif // USE_LIGHT
@ -947,6 +956,9 @@ void HueLights(String *path_req)
#ifdef USE_ZIGBEE
ZigbeeCheckHue(response, &appending);
#endif // USE_ZIGBEE
#ifdef USE_BERRY
be_hue_discovery(&response, &appending);
#endif
#ifdef USE_SCRIPT_HUE
Script_Check_Hue(&response);
#endif
@ -966,6 +978,13 @@ void HueLights(String *path_req)
}
#endif // USE_ZIGBEE
#ifdef USE_BERRY
if (be_hue_command(device, device_id, &response)) {
// code is already 200
goto exit;
}
#endif
#ifdef USE_SCRIPT_HUE
if (device > TasmotaGlobal.devices_present) {
return Script_Handle_Hue(path);
@ -992,6 +1011,12 @@ void HueLights(String *path_req)
}
#endif // USE_ZIGBEE
#ifdef USE_BERRY
if (be_hue_status(&response, device_id)) {
goto exit;
}
#endif
#ifdef USE_SCRIPT_HUE
if (device > TasmotaGlobal.devices_present) {
Script_HueStatus(&response, device-TasmotaGlobal.devices_present - 1);
@ -999,6 +1024,7 @@ void HueLights(String *path_req)
}
#endif
#ifdef USE_LIGHT
if ((device < 1) || (device > maxhue)) {
device = 1;
@ -1037,21 +1063,25 @@ void HueGroups(String *path)
if (path->endsWith(F("/0"))) {
UnishoxStrings msg(HUE_LIGHTS);
response = msg[HUE_GROUP0_STATUS_JSON];
String lights = F("\"1\"");
for (uint32_t i = 2; i <= maxhue; i++) {
String lights;
for (uint32_t i = 1; i <= maxhue; i++) {
lights += F(",\"");
lights += EncodeLightId(i);
lights += F("\"");
}
#ifdef USE_ZIGBEE
ZigbeeHueGroups(&response);
ZigbeeHueGroups(&lights);
#endif // USE_ZIGBEE
#ifdef USE_BERRY
be_hue_groups(&lights);
#endif
lights.remove(0,1); // remove first ','
response.replace(F("{l1"), lights);
#ifdef USE_LIGHT
HueLightStatus1(1, &response);
// HueLightStatus1(1, &response); // Not sure it is useful
#endif // USE_LIGHT
response += F("}");
response += F("{}}");
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " HueGroups Result (%s)"), path->c_str());

View File

@ -98,10 +98,12 @@ void HueLightStatus2Zigbee(uint16_t shortaddr, String *response)
char shortaddrname[8];
snprintf_P(shortaddrname, sizeof(shortaddrname), PSTR("0x%04X"), shortaddr);
HueLightStatus2Generic(response, (friendlyName) ? friendlyName : shortaddrname,
char* buf = HueLightStatus2Generic((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) {
@ -143,7 +145,7 @@ void ZigbeeHueGroups(String * lights) {
if (bulbtype >= 0) {
*lights += ",\"";
*lights += EncodeLightId(i);
*lights += EncodeLightId(0, shortaddr);
*lights += "\"";
}
}

View File

@ -0,0 +1,212 @@
/*
xdrv_52_3_berry_hue.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
#if defined(USE_EMULATION) && defined(USE_EMULATION_HUE)
#include "berry.h"
bool be_hue_status(String* response, uint32_t device_id);
bool be_hue_status(String* response, uint32_t device_id) {
bool handled = false;
// we need first to confirm if the `device_id` is ours
// If so, append json response, and return `true`
// otherwise ignore and respond `false``
bvm* vm = berry.vm;
if (be_getglobal(vm, "hue_bridge")) {
if (be_getmember(vm, -1, "full_status")) {
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_status found");
be_pushvalue(vm, -2);
be_pushint(vm, device_id);
int32_t ret = be_pcall(vm, 2); // 2 params: self, id
if (ret != 0) {
be_error_pop_all(berry.vm); // clear Berry stack
}
be_pop(vm, 2);
if (be_isstring(vm, -1)) {
const char* buf = be_tostring(vm, -1);
*response += buf;
handled = true;
}
be_pop(vm, 2);
return handled;
}
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_status response='%s' device_id=%i", response->c_str(), device_id);
}
be_pop(vm, 2);
return false;
}
// Discovery of devices
void be_hue_discovery(String* response, bool* appending);
void be_hue_discovery(String* response, bool* appending) {
bvm* vm = berry.vm;
if (be_getglobal(vm, "hue_bridge")) {
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_discovery hue_bridge found");
if (be_getmember(vm, -1, "discover")) {
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_discovery calling discovery");
be_pushvalue(vm, -2);
int32_t ret = be_pcall(vm, 1); // 2 params: self
if (ret != 0) {
be_error_pop_all(berry.vm); // clear Berry stack
}
be_pop(vm, 1);
if (be_isstring(vm, -1)) {
if (*appending) { *response += ","; }
*appending = true;
const char* buf = be_tostring(vm, -1);
*response += buf;
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_discovery added '%s'", buf);
}
}
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_discovery");
}
be_pop(vm, 2);
}
// Groups command, list all ids prefixed by ',', ex: ",11,23"
void be_hue_groups(String* response);
void be_hue_groups(String* response) {
bvm* vm = berry.vm;
if (be_getglobal(vm, "hue_bridge")) {
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_discovery hue_bridge found");
if (be_getmember(vm, -1, "groups")) {
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_discovery calling discovery");
be_pushvalue(vm, -2);
int32_t ret = be_pcall(vm, 1); // 2 params: self
if (ret != 0) {
be_error_pop_all(berry.vm); // clear Berry stack
}
be_pop(vm, 1);
if (be_isstring(vm, -1)) {
*response += ','; // prefix with comma
const char* buf = be_tostring(vm, -1);
*response += buf;
}
}
}
be_pop(vm, 2);
}
// handle incoming command
bool be_hue_command(uint8_t device, uint32_t device_id, String* response) {
bool handled = false;
// we need first to confirm if the `device_id` is ours
// If so, append json response, and return `true`
// otherwise ignore and respond `false``
bvm* vm = berry.vm;
if (be_getglobal(vm, "hue_bridge")) {
if (be_getmember(vm, -1, "cmd")) {
be_pushvalue(vm, -2);
be_pushint(vm, device_id);
String request_arg = Webserver->arg((Webserver->args())-1);
be_pushstring(vm, request_arg.c_str());
// be_pushint(vm, device);
int32_t ret = be_pcall(vm, 3); // 2 params: self, id, args
if (ret != 0) {
be_error_pop_all(berry.vm); // clear Berry stack
}
be_pop(vm, 3);
if (be_isstring(vm, -1)) {
const char* buf = be_tostring(vm, -1);
*response += buf;
handled = true;
}
be_pop(vm, 2);
return handled;
}
// AddLog(LOG_LEVEL_DEBUG_MORE, ">be_hue_status response='%s' device_id=%i", response->c_str(), device_id);
}
be_pop(vm, 2);
return false;
}
// idx: index in the list of zigbee_devices
// void be_hue_status1(String* response, const LightStateClass *l);
// void be_hue_status1(String* response, const LightStateClass *l) {
char* be_hue_light_state(class LightStateClass* l) {
// int be_ntv_hue_light_state(struct bvm *vm) {
static const char HUE_LIGHTS_STATUS_JSON1_SUFFIX_ZIGBEE[] =
"%s\"alert\":\"none\","
"\"effect\":\"none\","
"\"reachable\":%s}";
bool power = l->getPower();
bool reachable = l->getReachable();
uint8_t colormode = l->getColorMode();
uint8_t bri;
uint8_t sat;
uint16_t ct;
uint16_t hue;
float x, y;
uint32_t local_light_subtype = l->getSubType();
l->getHSB(&hue, &sat, NULL);
bri = l->getBri();
ct = l->getCT();
l->getXY(&x, &y);
uint16_t hue16 = l->getHue16();
uint32_t echo_gen = findEchoGeneration(); // 1 for 1st gen =+ Echo Dot 2nd gen, 2 for 2nd gen and above
if (bri > 254) bri = 254; // Philips Hue bri is between 1 and 254
if (bri < 1) bri = 1;
if (sat > 254) sat = 254; // Philips Hue only accepts 254 as max hue
const size_t buf_size = 256;
char * buf = (char*) malloc(buf_size); // temp buffer for strings, avoid stack
snprintf_P(buf, buf_size, PSTR("{\"on\":%s,"), power ? PSTR("true") : PSTR("false"));
// Brightness for all devices with PWM
if ((1 == echo_gen) || (LST_SINGLE <= local_light_subtype)) { // force dimmer for 1st gen Echo
snprintf_P(buf, buf_size, PSTR("%s\"bri\":%d,"), buf, bri);
}
if (LST_COLDWARM <= local_light_subtype) {
snprintf_P(buf, buf_size, PSTR("%s\"colormode\":\"%s\","), buf, (colormode & LCM_RGB) ? "hs" : "ct");
}
if (LST_RGB <= local_light_subtype) { // colors
snprintf_P(buf, buf_size, PSTR("%s\"xy\":[%s,%s],"), buf, String(x, 5).c_str(), String(y, 5).c_str());
snprintf_P(buf, buf_size, PSTR("%s\"hue\":%d,\"sat\":%d,"), buf, hue16, sat);
}
if (LST_COLDWARM == local_light_subtype || LST_RGBW <= local_light_subtype) { // white temp
snprintf_P(buf, buf_size, PSTR("%s\"ct\":%d,"), buf, ct > 0 ? ct : 284);
}
snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON1_SUFFIX_ZIGBEE, buf, reachable ? PSTR("true") : PSTR("false"));
return buf; // caller will call free() on it
}
char* be_hue_light_full_state(int32_t id, class LightStateClass* l, const char* name, const char* model, const char* manuf) {
static const char FULL_STATE[] = "{\"state\":%s%s";
char* buf_state = be_hue_light_state(l);
char* buf_suffix = HueLightStatus2Generic(name, model, manuf, GetHueDeviceId(id).c_str());
char* buf = ext_snprintf_malloc_P(FULL_STATE, buf_state, buf_suffix);
free(buf_state);
free(buf_suffix);
return buf; // caller will call `free()` on it
}
#endif // USE_LIGHT
#endif // USE_BERRY

View File

@ -24,110 +24,112 @@
#include "berry.h"
void* ls_init(int32_t channels) {
void* ls_init(int32_t type) {
if (type < 0 || type > LST_MAX) { return NULL; } // fail
LightStateClass * l = new LightStateClass();
l->setSubType(channels);
l->setSubType(type);
if (type == 2) { l->setColorMode(LCM_CT); }
return (LightStateClass*)l;
}
int32_t ls_r(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_r(class LightStateClass* l) {
uint8_t r;
l->getActualRGBCW(&r, NULL, NULL, NULL, NULL);
return r;
}
int32_t ls_g(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_g(class LightStateClass* l) {
uint8_t g;
l->getActualRGBCW(NULL, &g, NULL, NULL, NULL);
return g;
}
int32_t ls_b(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_b(class LightStateClass* l) {
uint8_t b;
l->getActualRGBCW(NULL, NULL, &b, NULL, NULL);
return b;
}
float ls_x(void* p) {
LightStateClass * l = (LightStateClass *) p;
float ls_x(class LightStateClass* l) {
float x;
l->getXY(&x, NULL);
return x;
}
float ls_y(void* p) {
LightStateClass * l = (LightStateClass *) p;
float ls_y(class LightStateClass* l) {
float y;
l->getXY(NULL, &y);
return y;
}
int32_t ls_hue(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_hue(class LightStateClass* l) {
uint16_t hue;
l->getHSB(&hue, NULL, NULL);
return hue;
}
int32_t ls_sat(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_hue16(class LightStateClass* l) {
return l->getHue16();
}
int32_t ls_sat(class LightStateClass* l) {
uint8_t sat;
l->getHSB(NULL, &sat, NULL);
return sat;
}
int32_t ls_bri(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_bri(class LightStateClass* l) {
return l->getBri();
}
int32_t ls_type(class LightStateClass* l) {
return l->getSubType();
}
void ls_set_rgb(void* p, int32_t r, int32_t g, int32_t b) {
LightStateClass * l = (LightStateClass *) p;
void ls_set_rgb(class LightStateClass* l, int32_t r, int32_t g, int32_t b) {
l->setRGB(r, g, b, false);
}
void ls_set_huesat(void* p, int32_t hue, int32_t sat) {
LightStateClass * l = (LightStateClass *) p;
void ls_set_huesat(class LightStateClass* l, int32_t hue, int32_t sat) {
l->setHS(hue, sat);
}
void ls_set_hue16sat(class LightStateClass* l, int32_t hue16, int32_t sat) {
l->setH16S(hue16, sat);
}
void ls_set_bri(class LightStateClass* l, int32_t bri) {
l->setBri(bri);
}
int32_t ls_get_power(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_get_power(class LightStateClass* l) {
return l->getPower();
}
void ls_set_xy(void* p, float x, float y) {
LightStateClass * l = (LightStateClass *) p;
void ls_set_xy(class LightStateClass* l, float x, float y) {
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;
void ls_set_power(class LightStateClass* l, int32_t pow) {
l->setPower(pow);
}
void ls_set_mode_rgb(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_reachable(class LightStateClass* l) {
return l->getReachable();
}
void ls_set_reachable(class LightStateClass* l, int32_t reachable) {
l->setReachable(reachable);
}
void ls_set_mode_rgb(class LightStateClass* l) {
l->setColorMode(LCM_RGB);
}
void ls_set_mode_ct(void* p) {
LightStateClass * l = (LightStateClass *) p;
void ls_set_mode_ct(class LightStateClass* l) {
l->setColorMode(LCM_CT);
}
int32_t ls_mode_rgb(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_mode_rgb(class LightStateClass* l) {
return (l->getColorMode() & LCM_RGB) ? 1 : 0;
}
int32_t ls_mode_ct(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_mode_ct(class LightStateClass* l) {
return (l->getColorMode() & LCM_CT) ? 1 : 0;
}
void ls_set_ct(void* p, int32_t ct) {
LightStateClass * l = (LightStateClass *) p;
void ls_set_ct(class LightStateClass* l, int32_t ct) {
l->setCT(ct);
l->setColorMode(LCM_CT);
}
int32_t ls_ct(void* p) {
LightStateClass * l = (LightStateClass *) p;
int32_t ls_ct(class LightStateClass* l) {
return l->getCT();
}
@ -159,12 +161,22 @@ extern "C" int light_state_get(bvm *vm) {
briCT = l->getBriCT();
bool mode_rgb = l->getColorMode() & LCM_RGB;
bool mode_ct = !mode_rgb;
// type
be_map_insert_int(vm, "type", sub_type);
// power
be_map_insert_bool(vm, "power", l->getPower());
// bri
if (sub_type > 0) {
be_map_insert_int(vm, "bri", l->getBri());
}
// color_mode
if (sub_type >= 3) {
be_map_insert_bool(vm, "mode_rgb", ls_mode_rgb(l));
if (sub_type >= 4) {
}
if (sub_type >= 4 || sub_type == 2) {
be_map_insert_bool(vm, "mode_ct", ls_mode_ct(l));
}
@ -182,6 +194,7 @@ extern "C" int light_state_get(bvm *vm) {
be_map_insert_int(vm, "ct", l->getCT());
}
if (sub_type > 0) {
uint8_t channels[LST_MAX] = {0};
switch (sub_type) {
case 1:
@ -200,8 +213,11 @@ extern "C" int light_state_get(bvm *vm) {
channels[3] = cw;
channels[4] = ww;
break;
default:
break;
}
be_map_insert_list_uint8(vm, "channels", channels, sub_type);
}
be_pop(vm, 1);
be_return(vm);

View File

@ -46,8 +46,6 @@ const char berry_prog[] =
"import autoconf "
#endif // USE_AUTOCONF
"import tapp "
#ifdef USE_LVGL
"import lv "
"import lv_tasmota "
@ -69,6 +67,13 @@ const char berry_prog[] =
#ifdef USE_LIGHT
"import light "
#endif // USE_LIGHT
#if defined(USE_EMULATION) && defined(USE_EMULATION_HUE)
"import hue_bridge "
#endif
"import tapp "
;
#endif // USE_BERRY