Skip to content

Commit

Permalink
Berry provide lightweight options for tasmota.wifi/eth/memory/rtc (a…
Browse files Browse the repository at this point in the history
  • Loading branch information
s-hadinger authored and hawa-lc4 committed Jan 20, 2024
1 parent 4a07dcb commit 0319c62
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 112 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
- Berry button to dynamically load GPIO Viewer with Berry backend (#20424)
- Berry `debug_panel.tapp` to display real-time heap and wifi rssi
- Berry `webserver.header` to read browser sent headers
- Berry provide lightweight options for `tasmota.wifi/eth/memory/rtc`

### Breaking Changed

Expand Down
105 changes: 74 additions & 31 deletions lib/libesp32/berry_mapping/src/be_mapping_utils.c
Expand Up @@ -8,61 +8,104 @@
/* Insert an nil to a key */
void be_map_insert_nil(bvm *vm, const char *key)
{
be_pushstring(vm, key);
be_pushnil(vm);
be_data_insert(vm, -3);
be_pop(vm, 2);
if (be_ismap(vm, -1)) {
be_pushstring(vm, key);
be_pushnil(vm);
be_data_insert(vm, -3);
be_pop(vm, 2);
}
}
/* Insert an int to a key */
// On stack is either:
// Case 1; (-2) map instance, (-1) map
// Case 2; (-2) nil, (-1) string -> if key matches then update (-2)
void be_map_insert_int(bvm *vm, const char *key, bint value)
{
be_pushstring(vm, key);
be_pushint(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
if (be_ismap(vm, -1)) {
be_pushstring(vm, key);
be_pushint(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
} else if (be_isstring(vm, -1)) {
const char * needle = be_tostring(vm, -1);
if (strcmp(key, needle) == 0) {
be_pushint(vm, value);
be_moveto(vm, -1, -3);
be_pop(vm, 1);
}
}
}
/* Insert an bbool to a key */
void be_map_insert_bool(bvm *vm, const char *key, bbool value)
{
be_pushstring(vm, key);
be_pushbool(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
if (be_ismap(vm, -1)) {
be_pushstring(vm, key);
be_pushbool(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
} else if (be_isstring(vm, -1)) {
const char * needle = be_tostring(vm, -1);
if (strcmp(key, needle) == 0) {
be_pushbool(vm, value);
be_moveto(vm, -1, -3);
be_pop(vm, 1);
}
}
}
/* Insert an real to a key */
/* if value == NAN, ignore */
void be_map_insert_real(bvm *vm, const char *key, breal value)
{
if (!isnan(value)) {
be_pushstring(vm, key);
be_pushreal(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
if (be_ismap(vm, -1)) {
if (!isnan(value)) {
be_pushstring(vm, key);
be_pushreal(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
}
} else if (be_isstring(vm, -1)) {
const char * needle = be_tostring(vm, -1);
if (strcmp(key, needle) == 0) {
be_pushreal(vm, value);
be_moveto(vm, -1, -3);
be_pop(vm, 1);
}
}
}
/* Insert an C string to a key */
void be_map_insert_str(bvm *vm, const char *key, const char *value)
{
be_pushstring(vm, key);
be_pushstring(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
if (be_ismap(vm, -1)) {
be_pushstring(vm, key);
be_pushstring(vm, value);
be_data_insert(vm, -3);
be_pop(vm, 2);
} else if (be_isstring(vm, -1)) {
const char * needle = be_tostring(vm, -1);
if (strcmp(key, needle) == 0) {
be_pushstring(vm, value);
be_moveto(vm, -1, -3);
be_pop(vm, 1);
}
}
}
/* Insert list of bytes as individual integers to a key */
void be_map_insert_list_uint8(bvm *vm, const char *key, const uint8_t *value, size_t size)
{
be_pushstring(vm, key);
if (be_ismap(vm, -1)) {
be_pushstring(vm, key);

be_newobject(vm, "list");
for (uint32_t i=0; i < size; i++) {
be_pushint(vm, value[i]);
be_data_push(vm, -2);
be_pop(vm, 1);
}
be_pop(vm, 1); // now list is on top
be_newobject(vm, "list");
for (uint32_t i=0; i < size; i++) {
be_pushint(vm, value[i]);
be_data_push(vm, -2);
be_pop(vm, 1);
}
be_pop(vm, 1); // now list is on top

be_data_insert(vm, -3); // insert into map, key/value
be_pop(vm, 2); // pop both key and value
be_data_insert(vm, -3); // insert into map, key/value
be_pop(vm, 2); // pop both key and value
}
}

/*********************************************************************************************\
Expand Down
8 changes: 4 additions & 4 deletions lib/libesp32/berry_tasmota/src/be_tasmota_lib.c
Expand Up @@ -111,14 +111,14 @@ class be_class_tasmota (scope: global, name: Tasmota) {
get_option, func(l_getoption)
millis, func(l_millis)
time_reached, func(l_timereached)
rtc, func(l_rtc)
rtc, static_func(l_rtc)
rtc_utc, func(l_rtc_utc)
time_dump, func(l_time_dump)
strftime, func(l_strftime)
strptime, func(l_strptime)
memory, func(l_memory)
wifi, func(l_wifi)
eth, func(l_eth)
memory, static_func(l_memory)
wifi, static_func(l_wifi)
eth, static_func(l_eth)
hostname, func(l_hostname)
yield, func(l_yield)
delay, func(l_delay)
Expand Down
170 changes: 93 additions & 77 deletions tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino
Expand Up @@ -171,16 +171,20 @@ extern "C" {
int32_t l_rtc(struct bvm *vm);
int32_t l_rtc(struct bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
if (top == 1) { // no argument (instance only)
if (top >= 1 && be_isstring(vm, 1)) { // argument is name
be_pushnil(vm);
be_pushvalue(vm, 1);
// (-2) nil, (-1) string -> if key matches then update (-2)
} else {
be_newobject(vm, "map");
be_map_insert_int(vm, "utc", Rtc.utc_time);
be_map_insert_int(vm, "local", Rtc.local_time);
be_map_insert_int(vm, "restart", Rtc.restart_time);
be_map_insert_int(vm, "timezone", Rtc.time_timezone);
be_pop(vm, 1);
be_return(vm);
// (-2) map instance, (-1) map
}
be_raise(vm, kTypeError, nullptr);
be_map_insert_int(vm, "utc", Rtc.utc_time);
be_map_insert_int(vm, "local", Rtc.local_time);
be_map_insert_int(vm, "restart", Rtc.restart_time);
be_map_insert_int(vm, "timezone", Rtc.time_timezone);
be_pop(vm, 1);
be_return(vm);
}

// Berry: tasmota.rtc_utc() -> int
Expand All @@ -196,102 +200,114 @@ extern "C" {
int32_t l_memory(struct bvm *vm);
int32_t l_memory(struct bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
if (top == 1) { // no argument (instance only)
if (top >= 1 && be_isstring(vm, 1)) { // argument is name
be_pushnil(vm);
be_pushvalue(vm, 1);
// (-2) nil, (-1) string -> if key matches then update (-2)
} else {
be_newobject(vm, "map");
be_map_insert_int(vm, "flash", ESP_getFlashChipMagicSize() / 1024);
be_map_insert_int(vm, "flash_real", ESP.getFlashChipSize() / 1024);
be_map_insert_int(vm, "program", ESP_getSketchSize() / 1024);
be_map_insert_int(vm, "program_free", ESP_getFreeSketchSpace() / 1024);
be_map_insert_int(vm, "heap_free", ESP_getFreeHeap() / 1024);
be_map_insert_int(vm, "frag", ESP_getHeapFragmentation());
// give info about stack size
be_map_insert_int(vm, "stack_size", SET_ESP32_STACK_SIZE / 1024);
be_map_insert_real(vm, "stack_low", ((float)uxTaskGetStackHighWaterMark(nullptr)) / 1024);
if (UsePSRAM()) {
be_map_insert_int(vm, "psram", ESP.getPsramSize() / 1024);
be_map_insert_int(vm, "psram_free", ESP.getFreePsram() / 1024);
}
// IRAM information
int32_t iram_free = (int32_t)heap_caps_get_free_size(MALLOC_CAP_32BIT) - (int32_t)heap_caps_get_free_size(MALLOC_CAP_8BIT);
be_map_insert_int(vm, "iram_free", iram_free / 1024);
be_pop(vm, 1);
be_return(vm);
// (-2) map instance, (-1) map
}
be_raise(vm, kTypeError, nullptr);
be_map_insert_int(vm, "flash", ESP_getFlashChipMagicSize() / 1024);
be_map_insert_int(vm, "flash_real", ESP.getFlashChipSize() / 1024);
be_map_insert_int(vm, "program", ESP_getSketchSize() / 1024);
be_map_insert_int(vm, "program_free", ESP_getFreeSketchSpace() / 1024);
be_map_insert_int(vm, "heap_free", ESP_getFreeHeap() / 1024);
be_map_insert_int(vm, "frag", ESP_getHeapFragmentation());
// give info about stack size
be_map_insert_int(vm, "stack_size", SET_ESP32_STACK_SIZE / 1024);
be_map_insert_real(vm, "stack_low", ((float)uxTaskGetStackHighWaterMark(nullptr)) / 1024);
if (UsePSRAM()) {
be_map_insert_int(vm, "psram", ESP.getPsramSize() / 1024);
be_map_insert_int(vm, "psram_free", ESP.getFreePsram() / 1024);
}
// IRAM information
int32_t iram_free = (int32_t)heap_caps_get_free_size(MALLOC_CAP_32BIT) - (int32_t)heap_caps_get_free_size(MALLOC_CAP_8BIT);
be_map_insert_int(vm, "iram_free", iram_free / 1024);
be_pop(vm, 1);
be_return(vm);
}

// Berry: tasmota.wifi() -> map
//
int32_t l_wifi(struct bvm *vm);
int32_t l_wifi(struct bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
if (top == 1) { // no argument (instance only)
if (top >= 1 && be_isstring(vm, 1)) { // argument is name
be_pushnil(vm);
be_pushvalue(vm, 1);
// (-2) nil, (-1) string -> if key matches then update (-2)
} else {
be_newobject(vm, "map");
be_map_insert_str(vm, "mac", WiFi.macAddress().c_str());
be_map_insert_bool(vm, "up", WifiHasIP());
if (Settings->flag4.network_wifi) {
int32_t rssi = WiFi.RSSI();
bool show_rssi = false;
// (-2) map instance, (-1) map
}
be_map_insert_str(vm, "mac", WiFi.macAddress().c_str());
be_map_insert_bool(vm, "up", WifiHasIP());
if (Settings->flag4.network_wifi) {
int32_t rssi = WiFi.RSSI();
bool show_rssi = false;
#ifdef USE_IPV6
String ipv6_addr = WifiGetIPv6Str();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6", ipv6_addr.c_str());
show_rssi = true;
}
ipv6_addr = WifiGetIPv6LinkLocalStr();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6local", ipv6_addr.c_str());
show_rssi = true;
}
String ipv6_addr = WifiGetIPv6Str();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6", ipv6_addr.c_str());
show_rssi = true;
}
ipv6_addr = WifiGetIPv6LinkLocalStr();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6local", ipv6_addr.c_str());
show_rssi = true;
}
#endif // USE_IPV6
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
be_map_insert_str(vm, "ip", IPAddress((uint32_t)WiFi.localIP()).toString().c_str()); // quick fix for IPAddress bug
show_rssi = true;
}
if (show_rssi) {
be_map_insert_int(vm, "rssi", rssi);
be_map_insert_int(vm, "quality", WifiGetRssiAsQuality(rssi));
}
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
be_map_insert_str(vm, "ip", IPAddress((uint32_t)WiFi.localIP()).toString().c_str()); // quick fix for IPAddress bug
show_rssi = true;
}
if (show_rssi) {
be_map_insert_int(vm, "rssi", rssi);
be_map_insert_int(vm, "quality", WifiGetRssiAsQuality(rssi));
}
be_pop(vm, 1);
be_return(vm);
}
be_raise(vm, kTypeError, nullptr);
be_pop(vm, 1);
be_return(vm);
}

// Berry: tasmota.eth() -> map
//
int32_t l_eth(struct bvm *vm);
int32_t l_eth(struct bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
if (top == 1) { // no argument (instance only)
if (top >= 1 && be_isstring(vm, 1)) { // argument is name
be_pushnil(vm);
be_pushvalue(vm, 1);
// (-2) nil, (-1) string -> if key matches then update (-2)
} else {
be_newobject(vm, "map");
// (-2) map instance, (-1) map
}
#ifdef USE_ETHERNET
be_map_insert_bool(vm, "up", EthernetHasIP());
String eth_mac = EthernetMacAddress().c_str();
if (eth_mac != "00:00:00:00:00:00") {
be_map_insert_str(vm, "mac", eth_mac.c_str());
}
if (static_cast<uint32_t>(EthernetLocalIP()) != 0) {
be_map_insert_str(vm, "ip", IPAddress((uint32_t)EthernetLocalIP()).toString().c_str()); // quick fix for IPAddress bug
}
be_map_insert_bool(vm, "up", EthernetHasIP());
String eth_mac = EthernetMacAddress().c_str();
if (eth_mac != "00:00:00:00:00:00") {
be_map_insert_str(vm, "mac", eth_mac.c_str());
}
if (static_cast<uint32_t>(EthernetLocalIP()) != 0) {
be_map_insert_str(vm, "ip", IPAddress((uint32_t)EthernetLocalIP()).toString().c_str()); // quick fix for IPAddress bug
}
#ifdef USE_IPV6
String ipv6_addr = EthernetGetIPv6Str();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6", ipv6_addr.c_str());
}
ipv6_addr = EthernetGetIPv6LinkLocalStr();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6local", ipv6_addr.c_str());
}
String ipv6_addr = EthernetGetIPv6Str();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6", ipv6_addr.c_str());
}
ipv6_addr = EthernetGetIPv6LinkLocalStr();
if (ipv6_addr != "") {
be_map_insert_str(vm, "ip6local", ipv6_addr.c_str());
}
#endif // USE_IPV6
#else // USE_ETHERNET
be_map_insert_bool(vm, "up", bfalse);
be_map_insert_bool(vm, "up", bfalse);
#endif // USE_ETHERNET
be_pop(vm, 1);
be_return(vm);
}
be_raise(vm, kTypeError, nullptr);
be_pop(vm, 1);
be_return(vm);
}

// Berry: tasmota.hostname() -> string
Expand Down

0 comments on commit 0319c62

Please sign in to comment.