mirror of https://github.com/arendst/Tasmota.git
Merge pull request #15686 from s-hadinger/berry_zigbee_phase_1
Berry zigbee phase 1
This commit is contained in:
commit
eb0cec4eb4
|
@ -48,6 +48,9 @@ be_extern_native_module(uuid);
|
||||||
be_extern_native_module(animate);
|
be_extern_native_module(animate);
|
||||||
be_extern_native_module(partition_core);
|
be_extern_native_module(partition_core);
|
||||||
be_extern_native_module(crc);
|
be_extern_native_module(crc);
|
||||||
|
#ifdef USE_ZIGBEE
|
||||||
|
be_extern_native_module(zigbee);
|
||||||
|
#endif // USE_ZIGBEE
|
||||||
#ifdef USE_LVGL
|
#ifdef USE_LVGL
|
||||||
be_extern_native_module(lv);
|
be_extern_native_module(lv);
|
||||||
be_extern_native_module(lv_extra);
|
be_extern_native_module(lv_extra);
|
||||||
|
@ -147,6 +150,9 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
&be_native_module(webserver),
|
&be_native_module(webserver),
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
|
#ifdef USE_ZIGBEE
|
||||||
|
&be_native_module(zigbee),
|
||||||
|
#endif // USE_ZIGBEE
|
||||||
&be_native_module(flash),
|
&be_native_module(flash),
|
||||||
&be_native_module(partition_core),
|
&be_native_module(partition_core),
|
||||||
&be_native_module(crc),
|
&be_native_module(crc),
|
||||||
|
|
|
@ -265,6 +265,7 @@ extern const bcstring be_const_str__timers;
|
||||||
extern const bcstring be_const_str__validate;
|
extern const bcstring be_const_str__validate;
|
||||||
extern const bcstring be_const_str__write;
|
extern const bcstring be_const_str__write;
|
||||||
extern const bcstring be_const_str_a;
|
extern const bcstring be_const_str_a;
|
||||||
|
extern const bcstring be_const_str_abort;
|
||||||
extern const bcstring be_const_str_abs;
|
extern const bcstring be_const_str_abs;
|
||||||
extern const bcstring be_const_str_acos;
|
extern const bcstring be_const_str_acos;
|
||||||
extern const bcstring be_const_str_active_otadata;
|
extern const bcstring be_const_str_active_otadata;
|
||||||
|
@ -569,6 +570,7 @@ extern const bcstring be_const_str_imax;
|
||||||
extern const bcstring be_const_str_img;
|
extern const bcstring be_const_str_img;
|
||||||
extern const bcstring be_const_str_imin;
|
extern const bcstring be_const_str_imin;
|
||||||
extern const bcstring be_const_str_import;
|
extern const bcstring be_const_str_import;
|
||||||
|
extern const bcstring be_const_str_info;
|
||||||
extern const bcstring be_const_str_init;
|
extern const bcstring be_const_str_init;
|
||||||
extern const bcstring be_const_str_init_draw_arc_dsc;
|
extern const bcstring be_const_str_init_draw_arc_dsc;
|
||||||
extern const bcstring be_const_str_init_draw_line_dsc;
|
extern const bcstring be_const_str_init_draw_line_dsc;
|
||||||
|
@ -1032,5 +1034,9 @@ extern const bcstring be_const_str_y;
|
||||||
extern const bcstring be_const_str_y1;
|
extern const bcstring be_const_str_y1;
|
||||||
extern const bcstring be_const_str_year;
|
extern const bcstring be_const_str_year;
|
||||||
extern const bcstring be_const_str_yield;
|
extern const bcstring be_const_str_yield;
|
||||||
|
extern const bcstring be_const_str_zb_coord_ntv;
|
||||||
|
extern const bcstring be_const_str_zb_device;
|
||||||
|
extern const bcstring be_const_str_zcl_frame;
|
||||||
|
extern const bcstring be_const_str_zcl_frame_ntv;
|
||||||
extern const bcstring be_const_str_zero;
|
extern const bcstring be_const_str_zero;
|
||||||
extern const bcstring be_const_str_zip;
|
extern const bcstring be_const_str_zip;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
static be_define_const_map_slots(be_class_zb_coord_ntv_map) {
|
||||||
|
{ be_const_key(iter, -1), be_const_func(zc_iter) },
|
||||||
|
{ be_const_key(zcl_frame, -1), be_const_class(be_class_zcl_frame) },
|
||||||
|
{ be_const_key(zb_device, 3), be_const_class(be_class_zb_device) },
|
||||||
|
{ be_const_key(info, -1), be_const_func(zc_info) },
|
||||||
|
{ be_const_key(size, 1), be_const_ctype_func(zc_size) },
|
||||||
|
{ be_const_key(item, -1), be_const_func(zc_item) },
|
||||||
|
{ be_const_key(abort, 4), be_const_ctype_func(zc_abort) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static be_define_const_map(
|
||||||
|
be_class_zb_coord_ntv_map,
|
||||||
|
7
|
||||||
|
);
|
||||||
|
|
||||||
|
BE_EXPORT_VARIABLE be_define_const_class(
|
||||||
|
be_class_zb_coord_ntv,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
zb_coord_ntv
|
||||||
|
);
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
static be_define_const_map_slots(be_class_zb_device_map) {
|
||||||
|
{ be_const_key(init, -1), be_const_ctype_func(zd_init) },
|
||||||
|
{ be_const_key(tostring, -1), be_const_closure(zb_device_tostring_closure) },
|
||||||
|
{ be_const_key(_p, -1), be_const_var(0) },
|
||||||
|
{ be_const_key(member, 0), be_const_func(zd_member) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static be_define_const_map(
|
||||||
|
be_class_zb_device_map,
|
||||||
|
4
|
||||||
|
);
|
||||||
|
|
||||||
|
BE_EXPORT_VARIABLE be_define_const_class(
|
||||||
|
be_class_zb_device,
|
||||||
|
1,
|
||||||
|
NULL,
|
||||||
|
zb_device
|
||||||
|
);
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
static be_define_const_map_slots(be_class_zcl_frame_ntv_map) {
|
||||||
|
{ be_const_key(_def, -1), be_const_comptr(&be_zigbee_zcl_frame_struct) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static be_define_const_map(
|
||||||
|
be_class_zcl_frame_ntv_map,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
BE_EXPORT_VARIABLE be_define_const_class(
|
||||||
|
be_class_zcl_frame_ntv,
|
||||||
|
0,
|
||||||
|
(bclass *)&be_class_ctypes_bytes,
|
||||||
|
zcl_frame_ntv
|
||||||
|
);
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
static be_define_const_map_slots(m_libzigbee_map) {
|
||||||
|
{ be_const_key(init, -1), be_const_func(zigbee_init) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static be_define_const_map(
|
||||||
|
m_libzigbee_map,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
static be_define_const_module(
|
||||||
|
m_libzigbee,
|
||||||
|
"zigbee"
|
||||||
|
);
|
||||||
|
|
||||||
|
BE_EXPORT_VARIABLE be_define_const_native_module(zigbee);
|
|
@ -76,6 +76,7 @@ static bbool be_const_member_dual(bvm *vm, const be_const_member_t * definitions
|
||||||
case '>': // call to a ctype function
|
case '>': // call to a ctype function
|
||||||
{
|
{
|
||||||
be_ctype_var_args_t* args = (be_ctype_var_args_t*) definitions[idx].value;
|
be_ctype_var_args_t* args = (be_ctype_var_args_t*) definitions[idx].value;
|
||||||
|
be_pop(vm, be_top(vm) - 1); // make sure we have only the instance left on the stack
|
||||||
int ret = be_call_c_func(vm, args->func, args->return_type, NULL);
|
int ret = be_call_c_func(vm, args->func, args->return_type, NULL);
|
||||||
if ((ret == BE_OK) && !be_isnil(vm, -1)) {
|
if ((ret == BE_OK) && !be_isnil(vm, -1)) {
|
||||||
return btrue;
|
return btrue;
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
/********************************************************************
|
||||||
|
* Zigbee
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
#ifdef USE_ZIGBEE
|
||||||
|
|
||||||
|
#include "be_constobj.h"
|
||||||
|
#include "be_mapping.h"
|
||||||
|
#include "be_ctypes.h"
|
||||||
|
|
||||||
|
#ifndef ARRAY_SIZE
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const void * zd_init(void* d); BE_FUNC_CTYPE_DECLARE(zd_init, "+_p", "c")
|
||||||
|
|
||||||
|
extern int32_t zd_shortaddr(void* d); BE_VAR_CTYPE_DECLARE(zd_shortaddr, "i");
|
||||||
|
extern const void* zd_longaddr(void* d, size_t *size, void* p2); BE_VAR_CTYPE_DECLARE(zd_longaddr, "&");
|
||||||
|
extern const char* zd_manufacturer(void* d); BE_VAR_CTYPE_DECLARE(zd_manufacturer, "s");
|
||||||
|
extern const char* zd_model(void* d); BE_VAR_CTYPE_DECLARE(zd_model, "s");
|
||||||
|
extern const char* zd_name(void* d); BE_VAR_CTYPE_DECLARE(zd_name, "s");
|
||||||
|
extern bbool zd_router(void* d); BE_VAR_CTYPE_DECLARE(zd_router, "b");
|
||||||
|
extern bbool zd_hidden(void* d); BE_VAR_CTYPE_DECLARE(zd_hidden, "b");
|
||||||
|
extern bbool zd_reachable(void* d); BE_VAR_CTYPE_DECLARE(zd_reachable, "b");
|
||||||
|
extern int32_t zd_lastseen(void* d); BE_VAR_CTYPE_DECLARE(zd_lastseen, "i");
|
||||||
|
extern int32_t zd_lqi(void* d); BE_VAR_CTYPE_DECLARE(zd_lqi, "i");
|
||||||
|
extern int32_t zd_battery(void* d); BE_VAR_CTYPE_DECLARE(zd_battery, "i");
|
||||||
|
extern int32_t zd_battery_lastseen(void* d); BE_VAR_CTYPE_DECLARE(zd_battery_lastseen, "i");
|
||||||
|
|
||||||
|
// moved to constants array
|
||||||
|
// MUST BE STORED IN SORTED LIST
|
||||||
|
const be_const_member_t zd_members[] = {
|
||||||
|
{ ">battery", be_ctype(zd_battery) },
|
||||||
|
{ ">battery_lastseen", be_ctype(zd_battery_lastseen) },
|
||||||
|
{ ">hidden", be_ctype(zd_hidden) },
|
||||||
|
{ ">lastseen", be_ctype(zd_lastseen) },
|
||||||
|
{ ">longaddr", be_ctype(zd_longaddr) },
|
||||||
|
{ ">lqi", be_ctype(zd_lqi) },
|
||||||
|
{ ">manufacturer", be_ctype(zd_manufacturer) },
|
||||||
|
{ ">model", be_ctype(zd_model) },
|
||||||
|
{ ">name", be_ctype(zd_name) },
|
||||||
|
{ ">reachable", be_ctype(zd_reachable) },
|
||||||
|
{ ">router", be_ctype(zd_router) },
|
||||||
|
{ ">shortaddr", be_ctype(zd_shortaddr) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int zd_member(bvm *vm) {
|
||||||
|
if (be_const_class_member(vm, zd_members, ARRAY_SIZE(zd_members))) {
|
||||||
|
be_return(vm);
|
||||||
|
} else {
|
||||||
|
be_return_nil(vm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int zc_info(struct bvm *vm);
|
||||||
|
extern int zc_item(struct bvm *vm);
|
||||||
|
extern int32_t zc_size(void* d); BE_FUNC_CTYPE_DECLARE(zc_size, "i", ".");
|
||||||
|
extern int zc_iter(bvm *vm);
|
||||||
|
extern void zc_abort(void); BE_FUNC_CTYPE_DECLARE(zc_abort, "", ".");
|
||||||
|
|
||||||
|
extern const bclass be_class_ctypes_bytes;
|
||||||
|
extern const be_ctypes_structure_t be_zigbee_zcl_frame_struct;
|
||||||
|
extern const bclass be_class_zcl_frame;
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: tostring
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zb_device_tostring, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
14, /* nstack */
|
||||||
|
1, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[11]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str_literal("json"),
|
||||||
|
/* K1 */ be_nested_str_literal("string"),
|
||||||
|
/* K2 */ be_nested_str_literal("longaddr"),
|
||||||
|
/* K3 */ be_nested_str_literal("format"),
|
||||||
|
/* K4 */ be_nested_str_literal("<instance: %s(0x%04X, 0x%08X%08X, name:'%s', model:'%s', manufacturer:'%s')>"),
|
||||||
|
/* K5 */ be_nested_str_literal("shortaddr"),
|
||||||
|
/* K6 */ be_nested_str_literal("get"),
|
||||||
|
/* K7 */ be_const_int(0),
|
||||||
|
/* K8 */ be_nested_str_literal("name"),
|
||||||
|
/* K9 */ be_nested_str_literal("model"),
|
||||||
|
/* K10 */ be_nested_str_literal("manufacturer"),
|
||||||
|
}),
|
||||||
|
be_str_literal("tostring"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[22]) { /* code */
|
||||||
|
0xA4060000, // 0000 IMPORT R1 K0
|
||||||
|
0xA40A0200, // 0001 IMPORT R2 K1
|
||||||
|
0x880C0102, // 0002 GETMBR R3 R0 K2
|
||||||
|
0x8C100503, // 0003 GETMET R4 R2 K3
|
||||||
|
0x58180004, // 0004 LDCONST R6 K4
|
||||||
|
0x601C0005, // 0005 GETGBL R7 G5
|
||||||
|
0x5C200000, // 0006 MOVE R8 R0
|
||||||
|
0x7C1C0200, // 0007 CALL R7 1
|
||||||
|
0x88200105, // 0008 GETMBR R8 R0 K5
|
||||||
|
0x8C240706, // 0009 GETMET R9 R3 K6
|
||||||
|
0x542E0003, // 000A LDINT R11 4
|
||||||
|
0x54320003, // 000B LDINT R12 4
|
||||||
|
0x7C240600, // 000C CALL R9 3
|
||||||
|
0x8C280706, // 000D GETMET R10 R3 K6
|
||||||
|
0x58300007, // 000E LDCONST R12 K7
|
||||||
|
0x54360003, // 000F LDINT R13 4
|
||||||
|
0x7C280600, // 0010 CALL R10 3
|
||||||
|
0x882C0108, // 0011 GETMBR R11 R0 K8
|
||||||
|
0x88300109, // 0012 GETMBR R12 R0 K9
|
||||||
|
0x8834010A, // 0013 GETMBR R13 R0 K10
|
||||||
|
0x7C101200, // 0014 CALL R4 9
|
||||||
|
0x80040800, // 0015 RET 1 R4
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
// Module Zigbee
|
||||||
|
extern const bclass be_class_zb_coord;
|
||||||
|
static int zigbee_init(bvm *vm) {
|
||||||
|
be_pushntvclass(vm, &be_class_zb_coord);
|
||||||
|
be_call(vm, 0);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "be_fixed_be_class_zb_device.h"
|
||||||
|
#include "be_fixed_be_class_zb_coord_ntv.h"
|
||||||
|
#include "be_fixed_be_class_zcl_frame_ntv.h"
|
||||||
|
#include "be_fixed_zigbee.h"
|
||||||
|
|
||||||
|
/* @const_object_info_begin
|
||||||
|
class be_class_zb_device (scope: global, name: zb_device) {
|
||||||
|
_p, var
|
||||||
|
init, ctype_func(zd_init)
|
||||||
|
|
||||||
|
member, func(zd_member)
|
||||||
|
|
||||||
|
tostring, closure(zb_device_tostring_closure)
|
||||||
|
}
|
||||||
|
@const_object_info_end */
|
||||||
|
|
||||||
|
/* @const_object_info_begin
|
||||||
|
class be_class_zb_coord_ntv (scope: global, name: zb_coord_ntv) {
|
||||||
|
zcl_frame, class(be_class_zcl_frame)
|
||||||
|
zb_device, class(be_class_zb_device)
|
||||||
|
|
||||||
|
info, func(zc_info)
|
||||||
|
item, func(zc_item)
|
||||||
|
size, ctype_func(zc_size)
|
||||||
|
iter, func(zc_iter)
|
||||||
|
|
||||||
|
abort, ctype_func(zc_abort)
|
||||||
|
}
|
||||||
|
@const_object_info_end */
|
||||||
|
|
||||||
|
|
||||||
|
/* @const_object_info_begin
|
||||||
|
class be_class_zcl_frame_ntv (scope: global, name: zcl_frame_ntv, super: be_class_ctypes_bytes) {
|
||||||
|
_def, comptr(&be_zigbee_zcl_frame_struct)
|
||||||
|
}
|
||||||
|
@const_object_info_end */
|
||||||
|
|
||||||
|
/* @const_object_info_begin
|
||||||
|
module zigbee (scope: global) {
|
||||||
|
init, func(zigbee_init)
|
||||||
|
}
|
||||||
|
@const_object_info_end */
|
||||||
|
|
||||||
|
#endif // USE_LIGHT
|
|
@ -0,0 +1,214 @@
|
||||||
|
/********************************************************************
|
||||||
|
* Zigbee
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
#ifdef USE_ZIGBEE
|
||||||
|
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
extern const bclass be_class_zb_coord_ntv;
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: init
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zb_coord_init, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
3, /* 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_literal("init"),
|
||||||
|
}),
|
||||||
|
be_str_literal("init"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 6]) { /* code */
|
||||||
|
0x60040003, // 0000 GETGBL R1 G3
|
||||||
|
0x5C080000, // 0001 MOVE R2 R0
|
||||||
|
0x7C040200, // 0002 CALL R1 1
|
||||||
|
0x8C040300, // 0003 GETMET R1 R1 K0
|
||||||
|
0x7C040200, // 0004 CALL R1 1
|
||||||
|
0x80000000, // 0005 RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: add_handler
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zb_coord_add_handler, /* 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[ 5]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str_literal("instance"),
|
||||||
|
/* K1 */ be_nested_str_literal("value_error"),
|
||||||
|
/* K2 */ be_nested_str_literal("instance required"),
|
||||||
|
/* K3 */ be_nested_str_literal("_handlers"),
|
||||||
|
/* K4 */ be_nested_str_literal("push"),
|
||||||
|
}),
|
||||||
|
be_str_literal("add_handler"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[18]) { /* code */
|
||||||
|
0x60080004, // 0000 GETGBL R2 G4
|
||||||
|
0x5C0C0200, // 0001 MOVE R3 R1
|
||||||
|
0x7C080200, // 0002 CALL R2 1
|
||||||
|
0x20080500, // 0003 NE R2 R2 K0
|
||||||
|
0x780A0000, // 0004 JMPF R2 #0006
|
||||||
|
0xB0060302, // 0005 RAISE 1 K1 K2
|
||||||
|
0x88080103, // 0006 GETMBR R2 R0 K3
|
||||||
|
0x780A0004, // 0007 JMPF R2 #000D
|
||||||
|
0x88080103, // 0008 GETMBR R2 R0 K3
|
||||||
|
0x8C080504, // 0009 GETMET R2 R2 K4
|
||||||
|
0x5C100200, // 000A MOVE R4 R1
|
||||||
|
0x7C080400, // 000B CALL R2 2
|
||||||
|
0x70020003, // 000C JMP #0011
|
||||||
|
0x60080012, // 000D GETGBL R2 G18
|
||||||
|
0x7C080000, // 000E CALL R2 0
|
||||||
|
0x400C0401, // 000F CONNECT R3 R2 R1
|
||||||
|
0x90020602, // 0010 SETMBR R0 K3 R2
|
||||||
|
0x80000000, // 0011 RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: dispatch
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zb_coord_dispatch, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
19, /* nstack */
|
||||||
|
5, /* 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_literal("_handlers"),
|
||||||
|
/* K1 */ be_nested_str_literal("introspect"),
|
||||||
|
/* K2 */ be_nested_str_literal("string"),
|
||||||
|
/* K3 */ be_nested_str_literal("zcl_frame"),
|
||||||
|
/* K4 */ be_const_int(0),
|
||||||
|
/* K5 */ be_nested_str_literal("get"),
|
||||||
|
/* K6 */ be_nested_str_literal("function"),
|
||||||
|
/* K7 */ be_nested_str_literal("format"),
|
||||||
|
/* K8 */ be_nested_str_literal("BRY: Exception> '%s' - %s"),
|
||||||
|
/* K9 */ be_nested_str_literal("tasmota"),
|
||||||
|
/* K10 */ be_nested_str_literal("_debug_present"),
|
||||||
|
/* K11 */ be_nested_str_literal("debug"),
|
||||||
|
/* K12 */ be_nested_str_literal("traceback"),
|
||||||
|
/* K13 */ be_const_int(1),
|
||||||
|
}),
|
||||||
|
be_str_literal("dispatch"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[61]) { /* code */
|
||||||
|
0x88140100, // 0000 GETMBR R5 R0 K0
|
||||||
|
0x4C180000, // 0001 LDNIL R6
|
||||||
|
0x1C140A06, // 0002 EQ R5 R5 R6
|
||||||
|
0x78160000, // 0003 JMPF R5 #0005
|
||||||
|
0x80000A00, // 0004 RET 0
|
||||||
|
0xA4160200, // 0005 IMPORT R5 K1
|
||||||
|
0xA41A0400, // 0006 IMPORT R6 K2
|
||||||
|
0x5C1C0600, // 0007 MOVE R7 R3
|
||||||
|
0x1C200503, // 0008 EQ R8 R2 K3
|
||||||
|
0x78220003, // 0009 JMPF R8 #000E
|
||||||
|
0x8C200103, // 000A GETMET R8 R0 K3
|
||||||
|
0x5C280600, // 000B MOVE R10 R3
|
||||||
|
0x7C200400, // 000C CALL R8 2
|
||||||
|
0x5C1C1000, // 000D MOVE R7 R8
|
||||||
|
0x58200004, // 000E LDCONST R8 K4
|
||||||
|
0x6024000C, // 000F GETGBL R9 G12
|
||||||
|
0x88280100, // 0010 GETMBR R10 R0 K0
|
||||||
|
0x7C240200, // 0011 CALL R9 1
|
||||||
|
0x14241009, // 0012 LT R9 R8 R9
|
||||||
|
0x78260027, // 0013 JMPF R9 #003C
|
||||||
|
0x88240100, // 0014 GETMBR R9 R0 K0
|
||||||
|
0x94241208, // 0015 GETIDX R9 R9 R8
|
||||||
|
0x8C280B05, // 0016 GETMET R10 R5 K5
|
||||||
|
0x5C301200, // 0017 MOVE R12 R9
|
||||||
|
0x5C340200, // 0018 MOVE R13 R1
|
||||||
|
0x7C280600, // 0019 CALL R10 3
|
||||||
|
0x602C0004, // 001A GETGBL R11 G4
|
||||||
|
0x5C301400, // 001B MOVE R12 R10
|
||||||
|
0x7C2C0200, // 001C CALL R11 1
|
||||||
|
0x1C2C1706, // 001D EQ R11 R11 K6
|
||||||
|
0x782E001A, // 001E JMPF R11 #003A
|
||||||
|
0xA8020008, // 001F EXBLK 0 #0029
|
||||||
|
0x5C2C1400, // 0020 MOVE R11 R10
|
||||||
|
0x5C301200, // 0021 MOVE R12 R9
|
||||||
|
0x5C340200, // 0022 MOVE R13 R1
|
||||||
|
0x5C380400, // 0023 MOVE R14 R2
|
||||||
|
0x5C3C0E00, // 0024 MOVE R15 R7
|
||||||
|
0x5C400800, // 0025 MOVE R16 R4
|
||||||
|
0x7C2C0A00, // 0026 CALL R11 5
|
||||||
|
0xA8040001, // 0027 EXBLK 1 1
|
||||||
|
0x70020010, // 0028 JMP #003A
|
||||||
|
0xAC2C0002, // 0029 CATCH R11 0 2
|
||||||
|
0x7002000D, // 002A JMP #0039
|
||||||
|
0x60340001, // 002B GETGBL R13 G1
|
||||||
|
0x8C380D07, // 002C GETMET R14 R6 K7
|
||||||
|
0x58400008, // 002D LDCONST R16 K8
|
||||||
|
0x5C441600, // 002E MOVE R17 R11
|
||||||
|
0x5C481800, // 002F MOVE R18 R12
|
||||||
|
0x7C380800, // 0030 CALL R14 4
|
||||||
|
0x7C340200, // 0031 CALL R13 1
|
||||||
|
0xB8361200, // 0032 GETNGBL R13 K9
|
||||||
|
0x88341B0A, // 0033 GETMBR R13 R13 K10
|
||||||
|
0x78360002, // 0034 JMPF R13 #0038
|
||||||
|
0xA4361600, // 0035 IMPORT R13 K11
|
||||||
|
0x8C381B0C, // 0036 GETMET R14 R13 K12
|
||||||
|
0x7C380200, // 0037 CALL R14 1
|
||||||
|
0x70020000, // 0038 JMP #003A
|
||||||
|
0xB0080000, // 0039 RAISE 2 R0 R0
|
||||||
|
0x0020110D, // 003A ADD R8 R8 K13
|
||||||
|
0x7001FFD2, // 003B JMP #000F
|
||||||
|
0x80000000, // 003C RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified class: zb_coord
|
||||||
|
********************************************************************/
|
||||||
|
extern const bclass be_class_zb_coord_ntv;
|
||||||
|
be_local_class(zb_coord,
|
||||||
|
1,
|
||||||
|
&be_class_zb_coord_ntv,
|
||||||
|
be_nested_map(4,
|
||||||
|
( (struct bmapnode*) &(const bmapnode[]) {
|
||||||
|
{ be_const_key_literal("dispatch", 1), be_const_closure(zb_coord_dispatch_closure) },
|
||||||
|
{ be_const_key_literal("add_handler", 2), be_const_closure(zb_coord_add_handler_closure) },
|
||||||
|
{ be_const_key_literal("_handlers", -1), be_const_var(0) },
|
||||||
|
{ be_const_key_literal("init", 0), be_const_closure(zb_coord_init_closure) },
|
||||||
|
})),
|
||||||
|
be_str_literal("zb_coord")
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
void be_load_zb_coord_class(bvm *vm) {
|
||||||
|
be_pushntvclass(vm, &be_class_zb_coord);
|
||||||
|
be_setglobal(vm, "zb_coord");
|
||||||
|
be_pop(vm, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // USE_LIGHT
|
|
@ -0,0 +1,255 @@
|
||||||
|
/********************************************************************
|
||||||
|
* Zigbee
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
#ifdef USE_ZIGBEE
|
||||||
|
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
extern const bclass be_class_zcl_frame_ntv;
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: member
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zcl_frame_member, /* 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[ 3]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str_literal("payload"),
|
||||||
|
/* K1 */ be_nested_str_literal("_get_bytes"),
|
||||||
|
/* K2 */ be_nested_str_literal("member"),
|
||||||
|
}),
|
||||||
|
be_str_literal("member"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[14]) { /* code */
|
||||||
|
0x1C080300, // 0000 EQ R2 R1 K0
|
||||||
|
0x780A0003, // 0001 JMPF R2 #0006
|
||||||
|
0x8C080101, // 0002 GETMET R2 R0 K1
|
||||||
|
0x7C080200, // 0003 CALL R2 1
|
||||||
|
0x80040400, // 0004 RET 1 R2
|
||||||
|
0x70020006, // 0005 JMP #000D
|
||||||
|
0x60080003, // 0006 GETGBL R2 G3
|
||||||
|
0x5C0C0000, // 0007 MOVE R3 R0
|
||||||
|
0x7C080200, // 0008 CALL R2 1
|
||||||
|
0x8C080502, // 0009 GETMET R2 R2 K2
|
||||||
|
0x5C100200, // 000A MOVE R4 R1
|
||||||
|
0x7C080400, // 000B CALL R2 2
|
||||||
|
0x80040400, // 000C RET 1 R2
|
||||||
|
0x80000000, // 000D RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: tomap
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zcl_frame_tomap, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
7, /* nstack */
|
||||||
|
1, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 7]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str_literal("string"),
|
||||||
|
/* K1 */ be_nested_str_literal("tomap"),
|
||||||
|
/* K2 */ be_nested_str_literal("shortaddr_hex"),
|
||||||
|
/* K3 */ be_nested_str_literal("format"),
|
||||||
|
/* K4 */ be_nested_str_literal("0x%04X"),
|
||||||
|
/* K5 */ be_nested_str_literal("shortaddr"),
|
||||||
|
/* K6 */ be_nested_str_literal("payload"),
|
||||||
|
}),
|
||||||
|
be_str_literal("tomap"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[14]) { /* code */
|
||||||
|
0xA4060000, // 0000 IMPORT R1 K0
|
||||||
|
0x60080003, // 0001 GETGBL R2 G3
|
||||||
|
0x5C0C0000, // 0002 MOVE R3 R0
|
||||||
|
0x7C080200, // 0003 CALL R2 1
|
||||||
|
0x8C080501, // 0004 GETMET R2 R2 K1
|
||||||
|
0x7C080200, // 0005 CALL R2 1
|
||||||
|
0x8C0C0303, // 0006 GETMET R3 R1 K3
|
||||||
|
0x58140004, // 0007 LDCONST R5 K4
|
||||||
|
0x88180105, // 0008 GETMBR R6 R0 K5
|
||||||
|
0x7C0C0600, // 0009 CALL R3 3
|
||||||
|
0x980A0403, // 000A SETIDX R2 K2 R3
|
||||||
|
0x880C0106, // 000B GETMBR R3 R0 K6
|
||||||
|
0x980A0C03, // 000C SETIDX R2 K6 R3
|
||||||
|
0x80040400, // 000D RET 1 R2
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: init
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zcl_frame_init, /* 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_literal("init"),
|
||||||
|
/* K1 */ be_nested_str_literal("no_bytes"),
|
||||||
|
}),
|
||||||
|
be_str_literal("init"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[10]) { /* code */
|
||||||
|
0x60080003, // 0000 GETGBL R2 G3
|
||||||
|
0x5C0C0000, // 0001 MOVE R3 R0
|
||||||
|
0x7C080200, // 0002 CALL R2 1
|
||||||
|
0x8C080500, // 0003 GETMET R2 R2 K0
|
||||||
|
0x5C100200, // 0004 MOVE R4 R1
|
||||||
|
0x7C080400, // 0005 CALL R2 2
|
||||||
|
0x60080015, // 0006 GETGBL R2 G21
|
||||||
|
0x7C080000, // 0007 CALL R2 0
|
||||||
|
0x90020202, // 0008 SETMBR R0 K1 R2
|
||||||
|
0x80000000, // 0009 RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: _get_bytes
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zcl_frame__get_bytes, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
10, /* nstack */
|
||||||
|
1, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 7]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str_literal("introspect"),
|
||||||
|
/* K1 */ be_nested_str_literal("toptr"),
|
||||||
|
/* K2 */ be_nested_str_literal("payload_ptr"),
|
||||||
|
/* K3 */ be_const_int(0),
|
||||||
|
/* K4 */ be_nested_str_literal("get"),
|
||||||
|
/* K5 */ be_const_int(2),
|
||||||
|
/* K6 */ be_nested_str_literal("no_bytes"),
|
||||||
|
}),
|
||||||
|
be_str_literal("_get_bytes"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[32]) { /* code */
|
||||||
|
0xA4060000, // 0000 IMPORT R1 K0
|
||||||
|
0x8C080301, // 0001 GETMET R2 R1 K1
|
||||||
|
0x88100102, // 0002 GETMBR R4 R0 K2
|
||||||
|
0x7C080400, // 0003 CALL R2 2
|
||||||
|
0x600C0009, // 0004 GETGBL R3 G9
|
||||||
|
0x5C100400, // 0005 MOVE R4 R2
|
||||||
|
0x7C0C0200, // 0006 CALL R3 1
|
||||||
|
0x200C0703, // 0007 NE R3 R3 K3
|
||||||
|
0x780E0013, // 0008 JMPF R3 #001D
|
||||||
|
0x600C0015, // 0009 GETGBL R3 G21
|
||||||
|
0x5C100400, // 000A MOVE R4 R2
|
||||||
|
0x5415FFFB, // 000B LDINT R5 -4
|
||||||
|
0x7C0C0400, // 000C CALL R3 2
|
||||||
|
0x8C100704, // 000D GETMET R4 R3 K4
|
||||||
|
0x58180005, // 000E LDCONST R6 K5
|
||||||
|
0x581C0005, // 000F LDCONST R7 K5
|
||||||
|
0x7C100600, // 0010 CALL R4 3
|
||||||
|
0x60140015, // 0011 GETGBL R5 G21
|
||||||
|
0x8C180301, // 0012 GETMET R6 R1 K1
|
||||||
|
0x60200009, // 0013 GETGBL R8 G9
|
||||||
|
0x5C240400, // 0014 MOVE R9 R2
|
||||||
|
0x7C200200, // 0015 CALL R8 1
|
||||||
|
0x54260003, // 0016 LDINT R9 4
|
||||||
|
0x00201009, // 0017 ADD R8 R8 R9
|
||||||
|
0x7C180400, // 0018 CALL R6 2
|
||||||
|
0x5C1C0800, // 0019 MOVE R7 R4
|
||||||
|
0x7C140400, // 001A CALL R5 2
|
||||||
|
0x80040A00, // 001B RET 1 R5
|
||||||
|
0x70020001, // 001C JMP #001F
|
||||||
|
0x880C0106, // 001D GETMBR R3 R0 K6
|
||||||
|
0x80040600, // 001E RET 1 R3
|
||||||
|
0x80000000, // 001F RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: tostring
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(zcl_frame_tostring, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
4, /* 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_literal("tomap"),
|
||||||
|
}),
|
||||||
|
be_str_literal("tostring"),
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 6]) { /* code */
|
||||||
|
0x8C040100, // 0000 GETMET R1 R0 K0
|
||||||
|
0x7C040200, // 0001 CALL R1 1
|
||||||
|
0x60080008, // 0002 GETGBL R2 G8
|
||||||
|
0x5C0C0200, // 0003 MOVE R3 R1
|
||||||
|
0x7C080200, // 0004 CALL R2 1
|
||||||
|
0x80040400, // 0005 RET 1 R2
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified class: zcl_frame
|
||||||
|
********************************************************************/
|
||||||
|
extern const bclass be_class_zcl_frame_ntv;
|
||||||
|
be_local_class(zcl_frame,
|
||||||
|
1,
|
||||||
|
&be_class_zcl_frame_ntv,
|
||||||
|
be_nested_map(6,
|
||||||
|
( (struct bmapnode*) &(const bmapnode[]) {
|
||||||
|
{ be_const_key_literal("no_bytes", -1), be_const_var(0) },
|
||||||
|
{ be_const_key_literal("member", 2), be_const_closure(zcl_frame_member_closure) },
|
||||||
|
{ be_const_key_literal("tostring", -1), be_const_closure(zcl_frame_tostring_closure) },
|
||||||
|
{ be_const_key_literal("init", -1), be_const_closure(zcl_frame_init_closure) },
|
||||||
|
{ be_const_key_literal("tomap", 5), be_const_closure(zcl_frame_tomap_closure) },
|
||||||
|
{ be_const_key_literal("_get_bytes", -1), be_const_closure(zcl_frame__get_bytes_closure) },
|
||||||
|
})),
|
||||||
|
be_str_literal("zcl_frame")
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
void be_load_zcl_frame_class(bvm *vm) {
|
||||||
|
be_pushntvclass(vm, &be_class_zcl_frame);
|
||||||
|
be_setglobal(vm, "zcl_frame");
|
||||||
|
be_pop(vm, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // USE_LIGHT
|
|
@ -0,0 +1,17 @@
|
||||||
|
# zigbee code
|
||||||
|
|
||||||
|
class zb_device
|
||||||
|
|
||||||
|
def tostring()
|
||||||
|
import json
|
||||||
|
import string
|
||||||
|
|
||||||
|
var la = self.longaddr # bytes() of size 8, little-endian
|
||||||
|
return string.format("<instance: %s(0x%04X, 0x%08X%08X, name:'%s', model:'%s', manufacturer:'%s')>",
|
||||||
|
classname(self), self.shortaddr,
|
||||||
|
la.get(4,4), la.get(0,4),
|
||||||
|
self.name, self.model, self.manufacturer)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,59 @@
|
||||||
|
# zigbee zcl_frame class
|
||||||
|
# solidify.dump(zb_coord,true)
|
||||||
|
|
||||||
|
class zb_coord_ntv end # fake class replaced with native one
|
||||||
|
#zb_coord_ntv = classof(super(zigbee))
|
||||||
|
|
||||||
|
class zb_coord : zb_coord_ntv
|
||||||
|
var _handlers
|
||||||
|
|
||||||
|
def init()
|
||||||
|
super(self).init()
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_handler(h)
|
||||||
|
if type(h) != 'instance'
|
||||||
|
raise "value_error", "instance required"
|
||||||
|
end
|
||||||
|
if self._handlers
|
||||||
|
self._handlers.push(h)
|
||||||
|
else
|
||||||
|
self._handlers = [h]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def dispatch(event_type, data_type, data_ptr, idx)
|
||||||
|
if self._handlers == nil return end
|
||||||
|
|
||||||
|
import introspect
|
||||||
|
import string
|
||||||
|
|
||||||
|
var data = data_ptr
|
||||||
|
if data_type == "zcl_frame"
|
||||||
|
data = self.zcl_frame(data_ptr)
|
||||||
|
end
|
||||||
|
|
||||||
|
#print(string.format(">ZIG: cmd=%s data_type=%s data=%s idx=%i", event_type, data_type, str(data), idx))
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
while i < size(self._handlers)
|
||||||
|
var h = self._handlers[i]
|
||||||
|
var f = introspect.get(h, event_type) # try to match a function or method with the same name
|
||||||
|
if type(f) == 'function'
|
||||||
|
try
|
||||||
|
f(h, event_type, data_type, data, idx)
|
||||||
|
except .. as e,m
|
||||||
|
print(string.format("BRY: Exception> '%s' - %s", e, m))
|
||||||
|
if tasmota._debug_present
|
||||||
|
import debug
|
||||||
|
debug.traceback()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# zigbee zcl_frame class
|
||||||
|
#
|
||||||
|
# solidify.dump(zcl_frame,true)
|
||||||
|
|
||||||
|
var zcl_frame_ntv = super(zcl_frame)
|
||||||
|
|
||||||
|
class zcl_frame : zcl_frame_ntv
|
||||||
|
var no_bytes
|
||||||
|
|
||||||
|
def init(p)
|
||||||
|
super(self).init(p)
|
||||||
|
self.no_bytes = bytes()
|
||||||
|
end
|
||||||
|
|
||||||
|
def member(name)
|
||||||
|
if name == "payload"
|
||||||
|
return self._get_bytes()
|
||||||
|
else
|
||||||
|
return super(self).member(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# return a bytes() object from a pre-populated zcl_frame payload
|
||||||
|
def _get_bytes()
|
||||||
|
import introspect
|
||||||
|
var payload_ptr = introspect.toptr(self.payload_ptr)
|
||||||
|
if int(payload_ptr) != 0
|
||||||
|
var sbuffer = bytes(payload_ptr, -4)
|
||||||
|
var sbuffer_len = sbuffer.get(2,2)
|
||||||
|
|
||||||
|
return bytes(introspect.toptr(int(payload_ptr) + 4), sbuffer_len)
|
||||||
|
else
|
||||||
|
return self.no_bytes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def tomap()
|
||||||
|
import string
|
||||||
|
var m = super(self).tomap()
|
||||||
|
m["shortaddr_hex"] = string.format("0x%04X", self.shortaddr)
|
||||||
|
m["payload"] = self.payload # add payload object which is a synthetic attribute not included in tomap()
|
||||||
|
return m
|
||||||
|
end
|
||||||
|
|
||||||
|
def tostring()
|
||||||
|
var m = self.tomap()
|
||||||
|
return str(m)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -73,7 +73,6 @@ public:
|
||||||
bool state_machine = false; // the state machine is running
|
bool state_machine = false; // the state machine is running
|
||||||
bool state_waiting = false; // the state machine is waiting for external event or timeout
|
bool state_waiting = false; // the state machine is waiting for external event or timeout
|
||||||
bool state_no_timeout = false; // the current wait loop does not generate a timeout but only continues running
|
bool state_no_timeout = false; // the current wait loop does not generate a timeout but only continues running
|
||||||
bool ready = false; // cc2530 initialization is complet, ready to operate
|
|
||||||
bool init_phase = true; // initialization phase, before accepting zigbee traffic
|
bool init_phase = true; // initialization phase, before accepting zigbee traffic
|
||||||
bool recv_until = false; // ignore all messages until the received frame fully matches
|
bool recv_until = false; // ignore all messages until the received frame fully matches
|
||||||
bool eeprom_present = false; // is the ZBBridge EEPROM present?
|
bool eeprom_present = false; // is the ZBBridge EEPROM present?
|
||||||
|
|
|
@ -995,7 +995,7 @@ private:
|
||||||
* Berry support
|
* Berry support
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
#ifdef USE_BERRY
|
#ifdef USE_BERRY
|
||||||
extern "C" void callBerryZigbeeDispatcher(const char* type, ZCLFrame* zcl_received);
|
extern "C" int32_t callBerryZigbeeDispatcher(const char* cmd, const char* type, void* data, int32_t idx);
|
||||||
#endif // USE_BERRY
|
#endif // USE_BERRY
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
|
|
@ -855,10 +855,10 @@ public:
|
||||||
uint16_t shortaddr = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid
|
uint16_t shortaddr = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid
|
||||||
uint8_t dstendpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
uint8_t dstendpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
||||||
// attributes used in send-only mode
|
// attributes used in send-only mode
|
||||||
bool clusterSpecific = false;
|
bool clusterSpecific = false;
|
||||||
bool needResponse = true;
|
bool needResponse = true;
|
||||||
bool direct = false; // true if direct, false if discover router
|
bool direct = false; // true if direct, false if discover router
|
||||||
bool transacSet = false; // is transac already set
|
bool transacSet = false; // is transac already set
|
||||||
|
|
||||||
// below private attributes are not used when sending a message
|
// below private attributes are not used when sending a message
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1641,7 +1641,7 @@ void Z_IncomingMessage(class ZCLFrame &zcl_received) {
|
||||||
|
|
||||||
#ifdef USE_BERRY
|
#ifdef USE_BERRY
|
||||||
// Berry pre-process messages
|
// Berry pre-process messages
|
||||||
// callBerryZigbeeDispatcher("pre", &zcl_received);
|
callBerryZigbeeDispatcher("incoming", "zcl_frame", &zcl_received, 0);
|
||||||
#endif // USE_BERRY
|
#endif // USE_BERRY
|
||||||
|
|
||||||
// create the device entry if it does not exist and if it's not the local device
|
// create the device entry if it does not exist and if it's not the local device
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
/*
|
||||||
|
xdrv_52_3_berry_zigbee.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_ZIGBEE
|
||||||
|
|
||||||
|
#include "berry.h"
|
||||||
|
#include "be_func.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern const bclass be_class_zb_device;
|
||||||
|
|
||||||
|
// Zigbee Device `zd`
|
||||||
|
const void* zd_init(const class Z_Device* device) {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t zd_shortaddr(const class Z_Device* d) {
|
||||||
|
return d->shortaddr;
|
||||||
|
}
|
||||||
|
const void* zd_longaddr(const class Z_Device* d, size_t *size, void* p2) {
|
||||||
|
*size = 8; // 64 bits
|
||||||
|
return &d->longaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* zd_manufacturer(const class Z_Device* d) {
|
||||||
|
return d->manufacturerId ? d->manufacturerId : "";
|
||||||
|
}
|
||||||
|
extern const char* zd_model(const class Z_Device* d) {
|
||||||
|
return d->modelId ? d->modelId : "";
|
||||||
|
}
|
||||||
|
extern const char* zd_name(const class Z_Device* d) {
|
||||||
|
return d->friendlyName ? d->friendlyName : "";
|
||||||
|
}
|
||||||
|
bool zd_router(const class Z_Device* d) {
|
||||||
|
return d->is_router;
|
||||||
|
}
|
||||||
|
bool zd_hidden(const class Z_Device* d) {
|
||||||
|
return d->hidden;
|
||||||
|
}
|
||||||
|
bool zd_reachable(const class Z_Device* d) {
|
||||||
|
return d->reachable;
|
||||||
|
}
|
||||||
|
int32_t zd_lastseen(const class Z_Device* d) {
|
||||||
|
return d->last_seen;
|
||||||
|
}
|
||||||
|
int32_t zd_lqi(const class Z_Device* d) {
|
||||||
|
return d->lqi == 255 ? -1 : d->lqi;
|
||||||
|
}
|
||||||
|
int32_t zd_battery(const class Z_Device* d) {
|
||||||
|
return d->batterypercent == 255 ? -1 : d->batterypercent;
|
||||||
|
}
|
||||||
|
int32_t zd_battery_lastseen(const class Z_Device* d) {
|
||||||
|
return 0; // TODO not yet known
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// Zigbee Coordinator `zc`
|
||||||
|
int zc_info(struct bvm *vm);
|
||||||
|
int zc_info(struct bvm *vm) {
|
||||||
|
int32_t top = be_top(vm); // Get the number of arguments
|
||||||
|
if (top == 1) { // no argument (instance only)
|
||||||
|
be_newobject(vm, "map");
|
||||||
|
be_map_insert_int(vm, "channel", Settings->zb_channel);
|
||||||
|
be_map_insert_int(vm, "tx_radio", Settings->zb_txradio_dbm);
|
||||||
|
char tmp[24];
|
||||||
|
ext_snprintf_P(tmp, sizeof(tmp), "0x%04X", Settings->zb_pan_id);
|
||||||
|
be_map_insert_str(vm, "pan_id_hex", tmp);
|
||||||
|
be_map_insert_int(vm, "pan_id", Settings->zb_pan_id);
|
||||||
|
ext_snprintf_P(tmp, sizeof(tmp), "0x%_X", &Settings->zb_ext_panid);
|
||||||
|
be_map_insert_str(vm, "ext_pan_id", tmp);
|
||||||
|
ext_snprintf_P(tmp, sizeof(tmp), "0x%04X", localShortAddr);
|
||||||
|
be_map_insert_str(vm, "shortaddr_hex", tmp);
|
||||||
|
be_map_insert_int(vm, "shortaddr", localShortAddr);
|
||||||
|
ext_snprintf_P(tmp, sizeof(tmp), "0x%_X", &localIEEEAddr);
|
||||||
|
be_map_insert_str(vm, "longaddr", tmp);
|
||||||
|
be_pop(vm, 1);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
be_raise(vm, kTypeError, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_item(struct bvm *vm);
|
||||||
|
int zc_item(struct bvm *vm) {
|
||||||
|
int32_t top = be_top(vm); // Get the number of arguments
|
||||||
|
if (zigbee.init_phase) {
|
||||||
|
be_raise(vm, "internal_error", "zigbee not started");
|
||||||
|
}
|
||||||
|
if (top >= 2 && (be_isint(vm, 2) || be_isstring(vm, 2))) {
|
||||||
|
const Z_Device & device = be_isint(vm, 2) ? zigbee_devices.findShortAddr(be_toint(vm, 2))
|
||||||
|
: zigbee_devices.parseDeviceFromName(be_tostring(vm, 2));
|
||||||
|
if (!device.valid()) {
|
||||||
|
be_raise(vm, "value_error", "unknown device");
|
||||||
|
}
|
||||||
|
|
||||||
|
be_pushntvclass(vm, &be_class_zb_device);
|
||||||
|
be_pushcomptr(vm, (void*) &device);
|
||||||
|
be_call(vm, 1);
|
||||||
|
be_pop(vm, 1);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
be_raise(vm, kTypeError, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t zc_size(void*) {
|
||||||
|
return zigbee_devices.devicesSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop zigbee, abort
|
||||||
|
// The abort state corresponds to state machine stopped but init not finished
|
||||||
|
void zc_abort(void) {
|
||||||
|
zigbee.active = false;
|
||||||
|
zigbee.state_machine = false; // not ready
|
||||||
|
zigbee.init_phase = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterator for devices in the coordinator's list of devices
|
||||||
|
// upval 0: index from 0 to size-1
|
||||||
|
static int zc_iter_closure(bvm *vm)
|
||||||
|
{
|
||||||
|
/* for better performance, we operate the upvalues
|
||||||
|
* directly without using by the stack. */
|
||||||
|
bntvclos *func = (bntvclos*) var_toobj(vm->cf->func);
|
||||||
|
bvalue *uv0 = be_ntvclos_upval(func, 0)->value;
|
||||||
|
bint idx = var_toint(uv0); /* upvalue[0] => lower */
|
||||||
|
if (idx >= zigbee_devices.devicesSize()) {
|
||||||
|
be_stop_iteration(vm);
|
||||||
|
}
|
||||||
|
var_toint(uv0) = idx + 1; /* set upvale[0] */
|
||||||
|
be_pushntvclass(vm, &be_class_zb_device);
|
||||||
|
const Z_Device & device = zigbee_devices.isKnownIndexDevice(idx);
|
||||||
|
be_pushcomptr(vm, (void*) &device);
|
||||||
|
be_call(vm, 1);
|
||||||
|
be_pop(vm, 1);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_iter(bvm *vm);
|
||||||
|
int zc_iter(bvm *vm) {
|
||||||
|
if (zigbee.init_phase) {
|
||||||
|
be_raise(vm, "internal_error", "zigbee not started");
|
||||||
|
}
|
||||||
|
be_pushntvclosure(vm, zc_iter_closure, 1);
|
||||||
|
be_pushint(vm, 0);
|
||||||
|
be_setupval(vm, -2, 0);
|
||||||
|
be_pop(vm, 1);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t callBerryZigbeeDispatcher(const char* cmd, const char* type, void* data, int32_t idx);
|
||||||
|
int32_t callBerryZigbeeDispatcher(const char* cmd, const char* type, void* data, int32_t idx) {
|
||||||
|
int32_t ret = 0;
|
||||||
|
bvm *vm = berry.vm;
|
||||||
|
|
||||||
|
if (nullptr == vm) { return ret; }
|
||||||
|
checkBeTop();
|
||||||
|
be_getglobal(vm, PSTR("zigbee")); // global object of type zb_coord()
|
||||||
|
if (!be_isnil(vm, -1)) {
|
||||||
|
be_getmethod(vm, -1, PSTR("dispatch")); // method dispatch
|
||||||
|
if (!be_isnil(vm, -1)) {
|
||||||
|
be_pushvalue(vm, -2); // add instance as first arg
|
||||||
|
be_pushstring(vm, cmd != nullptr ? cmd : "");
|
||||||
|
be_pushstring(vm, type != nullptr ? type : "");
|
||||||
|
be_pushcomptr(vm, data);
|
||||||
|
be_pushint(vm, idx);
|
||||||
|
BrTimeoutStart();
|
||||||
|
ret = be_pcall(vm, 5); // 5 arguments
|
||||||
|
BrTimeoutReset();
|
||||||
|
if (ret != 0) {
|
||||||
|
be_error_pop_all(berry.vm); // clear Berry stack
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
be_pop(vm, 5);
|
||||||
|
if (be_isint(vm, -1) || be_isbool(vm, -1)) {
|
||||||
|
if (be_isint(vm, -1)) { ret = be_toint(vm, -1); }
|
||||||
|
if (be_isbool(vm, -1)) { ret = be_tobool(vm, -1); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be_pop(vm, 1); // remove method
|
||||||
|
}
|
||||||
|
be_pop(vm, 1); // remove instance object
|
||||||
|
checkBeTop();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Mapping for zcl_message
|
||||||
|
*
|
||||||
|
\*********************************************************************************************/
|
||||||
|
extern "C" {
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Winvalid-offsetof" // avoid warnings since we're using offsetof() in a risky way
|
||||||
|
|
||||||
|
extern const be_ctypes_structure_t be_zigbee_zcl_frame_struct = {
|
||||||
|
sizeof(ZCLFrame), /* size in bytes */
|
||||||
|
12, /* number of elements */
|
||||||
|
nullptr,
|
||||||
|
(const be_ctypes_structure_item_t[12]) {
|
||||||
|
{ "cluster", offsetof(ZCLFrame, cluster), 0, 0, ctypes_u16, 0 },
|
||||||
|
{ "cluster_specific", offsetof(ZCLFrame, clusterSpecific), 0, 0, ctypes_u8, 0 },
|
||||||
|
{ "cmd", offsetof(ZCLFrame, cmd), 0, 0, ctypes_u8, 0 },
|
||||||
|
{ "direct", offsetof(ZCLFrame, direct), 0, 0, ctypes_u8, 0 },
|
||||||
|
{ "dstendpoint", offsetof(ZCLFrame, dstendpoint), 0, 0, ctypes_u8, 0 },
|
||||||
|
{ "groupaddr", offsetof(ZCLFrame, groupaddr), 0, 0, ctypes_u16, 0 },
|
||||||
|
{ "manuf", offsetof(ZCLFrame, manuf), 0, 0, ctypes_u16, 0 },
|
||||||
|
{ "need_response", offsetof(ZCLFrame, needResponse), 0, 0, ctypes_u8, 0 },
|
||||||
|
{ "payload_ptr", offsetof(ZCLFrame, payload), 0, 0, ctypes_ptr32, 0 },
|
||||||
|
{ "shortaddr", offsetof(ZCLFrame, shortaddr), 0, 0, ctypes_u16, 0 },
|
||||||
|
{ "transactseq", offsetof(ZCLFrame, transactseq), 0, 0, ctypes_u8, 0 },
|
||||||
|
{ "transactseq_set", offsetof(ZCLFrame, transacSet), 0, 0, ctypes_u8, 0 },
|
||||||
|
}};
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // USE_ZIGBEE
|
||||||
|
#endif // USE_BERRY
|
Loading…
Reference in New Issue