mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' of github.com:arendst/Tasmota into pr2_tm1637
This commit is contained in:
commit
269dadc55a
|
@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Berry language improved Tasmota integration
|
||||
- Filesystem commands ``Ufs``, ``UfsType``, ``UfsSize``, ``UfsFree``, ``UfsDelete``, ``UfsRename`` and ``UfsRun``
|
||||
- Basic support for filesystem ``autoexec.bat``
|
||||
- Berry add file system support
|
||||
|
||||
### Changed
|
||||
- IRremoteESP8266 library from v2.7.14 to v2.7.15
|
||||
|
|
|
@ -8,10 +8,14 @@
|
|||
#include "berry.h"
|
||||
#include "be_mem.h"
|
||||
#include "be_sys.h"
|
||||
#include <stdio.h>
|
||||
// #include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
// Local pointer for file managment
|
||||
#include <FS.h>
|
||||
extern FS *dfsp;
|
||||
|
||||
/* this file contains configuration for the file system. */
|
||||
|
||||
/* standard input and output */
|
||||
|
@ -47,9 +51,36 @@ extern "C" {
|
|||
}
|
||||
}
|
||||
|
||||
// We need to create a local buffer, since we might mess up mqtt_data
|
||||
#ifndef BERRY_LOGSZ
|
||||
#define BERRY_LOGSZ 128
|
||||
#endif
|
||||
static char log_berry_buffer[BERRY_LOGSZ] = { 0, };
|
||||
extern void berry_log(const char * berry_buf);
|
||||
|
||||
BERRY_API void be_writebuffer(const char *buffer, size_t length)
|
||||
{
|
||||
Serial.write(buffer, length);
|
||||
if (buffer == nullptr || length == 0) { return; }
|
||||
uint32_t idx = 0;
|
||||
while (idx < length) {
|
||||
int32_t cr_pos = -1;
|
||||
// find next occurence of '\n'
|
||||
for (uint32_t i = idx; i < length; i++) {
|
||||
if (buffer[i] == '\n') {
|
||||
cr_pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint32_t chars_to_append = (cr_pos >= 0) ? cr_pos - idx : length - idx; // note cr_pos < length
|
||||
snprintf(log_berry_buffer, sizeof(log_berry_buffer), "%s%.*s", log_berry_buffer, chars_to_append, buffer); // append at most `length` chars
|
||||
if (cr_pos >= 0) {
|
||||
// flush
|
||||
berry_log(log_berry_buffer);
|
||||
log_berry_buffer[0] = 0; // clear string
|
||||
}
|
||||
idx += chars_to_append + 1; // skip '\n'
|
||||
}
|
||||
// Serial.write(buffer, length);
|
||||
// be_fwrite(stdout, buffer, length);
|
||||
}
|
||||
|
||||
|
@ -63,54 +94,116 @@ BERRY_API char* be_readstring(char *buffer, size_t size)
|
|||
|
||||
void* be_fopen(const char *filename, const char *modes)
|
||||
{
|
||||
if (dfsp != nullptr && filename != nullptr && modes != nullptr) {
|
||||
// Serial.printf("be_fopen filename=%s, modes=%s\n", filename, modes);
|
||||
File f = dfsp->open(filename, modes); // returns an object, not a pointer
|
||||
if (f) {
|
||||
File * f_ptr = new File(f); // copy to dynamic object
|
||||
*f_ptr = f; // TODO is this necessary?
|
||||
return f_ptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
// return fopen(filename, modes);
|
||||
}
|
||||
|
||||
int be_fclose(void *hfile)
|
||||
{
|
||||
return 0;
|
||||
// Serial.printf("be_fclose\n");
|
||||
if (dfsp != nullptr && hfile != nullptr) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
f_ptr->close();
|
||||
delete f_ptr;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
// return fclose(hfile);
|
||||
}
|
||||
|
||||
size_t be_fwrite(void *hfile, const void *buffer, size_t length)
|
||||
{
|
||||
// Serial.printf("be_fwrite %d\n", length);
|
||||
if (dfsp != nullptr && hfile != nullptr && buffer != nullptr) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
return f_ptr->write((const uint8_t*) buffer, length);
|
||||
}
|
||||
return 0;
|
||||
// return fwrite(buffer, 1, length, hfile);
|
||||
}
|
||||
|
||||
size_t be_fread(void *hfile, void *buffer, size_t length)
|
||||
{
|
||||
// Serial.printf("be_fread %d\n", length);
|
||||
if (dfsp != nullptr && hfile != nullptr && buffer != nullptr) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
int32_t ret = f_ptr->read((uint8_t*) buffer, length);
|
||||
if (ret >= 0) {
|
||||
// Serial.printf("be_fread ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
// return fread(buffer, 1, length, hfile);
|
||||
}
|
||||
|
||||
char* be_fgets(void *hfile, void *buffer, int size)
|
||||
{
|
||||
// Serial.printf("be_fgets %d\n", size);
|
||||
uint8_t * buf = (uint8_t*) buffer;
|
||||
if (dfsp != nullptr && hfile != nullptr && buffer != nullptr && size > 0) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
int ret = f_ptr->readBytesUntil('\n', buf, size - 1);
|
||||
if (ret >= 0) {
|
||||
buf[ret] = 0; // add string terminator
|
||||
return (char*) buffer;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
// return fgets(buffer, size, hfile);
|
||||
}
|
||||
|
||||
int be_fseek(void *hfile, long offset)
|
||||
{
|
||||
return 0;
|
||||
// Serial.printf("be_fseek %d\n", offset);
|
||||
if (dfsp != nullptr && hfile != nullptr) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
if (f_ptr->seek(offset)) {
|
||||
return 0; // success
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
// return fseek(hfile, offset, SEEK_SET);
|
||||
}
|
||||
|
||||
long int be_ftell(void *hfile)
|
||||
{
|
||||
// Serial.printf("be_ftell\n");
|
||||
if (dfsp != nullptr && hfile != nullptr) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
return f_ptr->position();
|
||||
}
|
||||
return 0;
|
||||
// return ftell(hfile);
|
||||
}
|
||||
|
||||
long int be_fflush(void *hfile)
|
||||
{
|
||||
// Serial.printf("be_fflush\n");
|
||||
if (dfsp != nullptr && hfile != nullptr) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
f_ptr->flush();
|
||||
}
|
||||
return 0;
|
||||
// return fflush(hfile);
|
||||
}
|
||||
|
||||
size_t be_fsize(void *hfile)
|
||||
{
|
||||
// Serial.printf("be_fsize\n");
|
||||
if (dfsp != nullptr && hfile != nullptr) {
|
||||
File * f_ptr = (File*) hfile;
|
||||
return f_ptr->size();
|
||||
}
|
||||
// long int size, offset = be_ftell(hfile);
|
||||
// fseek(hfile, 0L, SEEK_END);
|
||||
// size = ftell(hfile);
|
||||
|
@ -121,233 +214,233 @@ size_t be_fsize(void *hfile)
|
|||
|
||||
|
||||
|
||||
// #if BE_USE_FILE_SYSTEM
|
||||
// #if defined(USE_FATFS) /* FatFs */
|
||||
#if BE_USE_FILE_SYSTEM
|
||||
#if defined(USE_FATFS) /* FatFs */
|
||||
|
||||
// int be_isdir(const char *path)
|
||||
// {
|
||||
// FILINFO fno;
|
||||
// FRESULT fr = f_stat(path, &fno);
|
||||
// return fr == FR_OK && fno.fattrib & AM_DIR;
|
||||
// }
|
||||
int be_isdir(const char *path)
|
||||
{
|
||||
FILINFO fno;
|
||||
FRESULT fr = f_stat(path, &fno);
|
||||
return fr == FR_OK && fno.fattrib & AM_DIR;
|
||||
}
|
||||
|
||||
// int be_isfile(const char *path)
|
||||
// {
|
||||
// FILINFO fno;
|
||||
// FRESULT fr = f_stat(path, &fno);
|
||||
// return fr == FR_OK && !(fno.fattrib & AM_DIR);
|
||||
// }
|
||||
int be_isfile(const char *path)
|
||||
{
|
||||
FILINFO fno;
|
||||
FRESULT fr = f_stat(path, &fno);
|
||||
return fr == FR_OK && !(fno.fattrib & AM_DIR);
|
||||
}
|
||||
|
||||
// int be_isexist(const char *path)
|
||||
// {
|
||||
// FILINFO fno;
|
||||
// return f_stat(path, &fno) == FR_OK;
|
||||
// }
|
||||
int be_isexist(const char *path)
|
||||
{
|
||||
FILINFO fno;
|
||||
return f_stat(path, &fno) == FR_OK;
|
||||
}
|
||||
|
||||
// char* be_getcwd(char *buf, size_t size)
|
||||
// {
|
||||
// FRESULT fr = f_getcwd(buf, (UINT)size);
|
||||
// return fr == FR_OK ? buf : NULL;
|
||||
// }
|
||||
char* be_getcwd(char *buf, size_t size)
|
||||
{
|
||||
FRESULT fr = f_getcwd(buf, (UINT)size);
|
||||
return fr == FR_OK ? buf : NULL;
|
||||
}
|
||||
|
||||
// int be_chdir(const char *path)
|
||||
// {
|
||||
// return f_chdir(path);
|
||||
// }
|
||||
int be_chdir(const char *path)
|
||||
{
|
||||
return f_chdir(path);
|
||||
}
|
||||
|
||||
// int be_mkdir(const char *path)
|
||||
// {
|
||||
// return f_mkdir(path);
|
||||
// }
|
||||
int be_mkdir(const char *path)
|
||||
{
|
||||
return f_mkdir(path);
|
||||
}
|
||||
|
||||
// int be_unlink(const char *filename)
|
||||
// {
|
||||
// return f_unlink(filename);
|
||||
// }
|
||||
int be_unlink(const char *filename)
|
||||
{
|
||||
return f_unlink(filename);
|
||||
}
|
||||
|
||||
// int be_dirfirst(bdirinfo *info, const char *path)
|
||||
// {
|
||||
// info->dir = be_os_malloc(sizeof(DIR));
|
||||
// info->file = be_os_malloc(sizeof(FILINFO));
|
||||
// if (info->dir && info->file) {
|
||||
// FRESULT fr = f_opendir(info->dir, path);
|
||||
// return fr == FR_OK ? be_dirnext(info) : 1;
|
||||
// }
|
||||
// be_os_free(info->dir);
|
||||
// be_os_free(info->file);
|
||||
// info->dir = NULL;
|
||||
// info->file = NULL;
|
||||
// return 1;
|
||||
// }
|
||||
int be_dirfirst(bdirinfo *info, const char *path)
|
||||
{
|
||||
info->dir = be_os_malloc(sizeof(DIR));
|
||||
info->file = be_os_malloc(sizeof(FILINFO));
|
||||
if (info->dir && info->file) {
|
||||
FRESULT fr = f_opendir(info->dir, path);
|
||||
return fr == FR_OK ? be_dirnext(info) : 1;
|
||||
}
|
||||
be_os_free(info->dir);
|
||||
be_os_free(info->file);
|
||||
info->dir = NULL;
|
||||
info->file = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// int be_dirnext(bdirinfo *info)
|
||||
// {
|
||||
// FRESULT fr = f_readdir(info->dir, info->file);
|
||||
// info->name = ((FILINFO *)info->file)->fname;
|
||||
// return fr != FR_OK || *info->name == '\0';
|
||||
// }
|
||||
int be_dirnext(bdirinfo *info)
|
||||
{
|
||||
FRESULT fr = f_readdir(info->dir, info->file);
|
||||
info->name = ((FILINFO *)info->file)->fname;
|
||||
return fr != FR_OK || *info->name == '\0';
|
||||
}
|
||||
|
||||
// int be_dirclose(bdirinfo *info)
|
||||
// {
|
||||
// if (info->dir) {
|
||||
// int res = f_closedir(info->dir) != FR_OK;
|
||||
// be_os_free(info->dir);
|
||||
// be_os_free(info->file);
|
||||
// return res;
|
||||
// }
|
||||
// return 1;
|
||||
// }
|
||||
int be_dirclose(bdirinfo *info)
|
||||
{
|
||||
if (info->dir) {
|
||||
int res = f_closedir(info->dir) != FR_OK;
|
||||
be_os_free(info->dir);
|
||||
be_os_free(info->file);
|
||||
return res;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// #elif defined(_MSC_VER) /* MSVC*/
|
||||
#elif defined(_MSC_VER) /* MSVC*/
|
||||
|
||||
// #include <windows.h>
|
||||
// #include <direct.h>
|
||||
// #include <io.h>
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
|
||||
// int be_isdir(const char *path)
|
||||
// {
|
||||
// DWORD type = GetFileAttributes(path);
|
||||
// return type != INVALID_FILE_ATTRIBUTES
|
||||
// && (type & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
// }
|
||||
int be_isdir(const char *path)
|
||||
{
|
||||
DWORD type = GetFileAttributes(path);
|
||||
return type != INVALID_FILE_ATTRIBUTES
|
||||
&& (type & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
// int be_isfile(const char *path)
|
||||
// {
|
||||
// DWORD type = GetFileAttributes(path);
|
||||
// return type != INVALID_FILE_ATTRIBUTES
|
||||
// && (type & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
// }
|
||||
int be_isfile(const char *path)
|
||||
{
|
||||
DWORD type = GetFileAttributes(path);
|
||||
return type != INVALID_FILE_ATTRIBUTES
|
||||
&& (type & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
}
|
||||
|
||||
// int be_isexist(const char *path)
|
||||
// {
|
||||
// return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES;
|
||||
// }
|
||||
int be_isexist(const char *path)
|
||||
{
|
||||
return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
// char* be_getcwd(char *buf, size_t size)
|
||||
// {
|
||||
// return _getcwd(buf, (int)size);
|
||||
// }
|
||||
char* be_getcwd(char *buf, size_t size)
|
||||
{
|
||||
return _getcwd(buf, (int)size);
|
||||
}
|
||||
|
||||
// int be_chdir(const char *path)
|
||||
// {
|
||||
// return _chdir(path);
|
||||
// }
|
||||
int be_chdir(const char *path)
|
||||
{
|
||||
return _chdir(path);
|
||||
}
|
||||
|
||||
// int be_mkdir(const char *path)
|
||||
// {
|
||||
// return _mkdir(path);
|
||||
// }
|
||||
int be_mkdir(const char *path)
|
||||
{
|
||||
return _mkdir(path);
|
||||
}
|
||||
|
||||
// int be_unlink(const char *filename)
|
||||
// {
|
||||
// return remove(filename);
|
||||
// }
|
||||
int be_unlink(const char *filename)
|
||||
{
|
||||
return remove(filename);
|
||||
}
|
||||
|
||||
// int be_dirfirst(bdirinfo *info, const char *path)
|
||||
// {
|
||||
// char *buf = be_os_malloc(strlen(path) + 3);
|
||||
// info->file = be_os_malloc(sizeof(struct _finddata_t));
|
||||
// info->dir = NULL;
|
||||
// if (buf && info->file) {
|
||||
// struct _finddata_t *cfile = info->file;
|
||||
// strcat(strcpy(buf, path), "/*");
|
||||
// info->dir = (void *)_findfirst(buf, cfile);
|
||||
// info->name = cfile->name;
|
||||
// be_os_free(buf);
|
||||
// return (intptr_t)info->dir == -1;
|
||||
// }
|
||||
// be_os_free(buf);
|
||||
// return 1;
|
||||
// }
|
||||
int be_dirfirst(bdirinfo *info, const char *path)
|
||||
{
|
||||
char *buf = be_os_malloc(strlen(path) + 3);
|
||||
info->file = be_os_malloc(sizeof(struct _finddata_t));
|
||||
info->dir = NULL;
|
||||
if (buf && info->file) {
|
||||
struct _finddata_t *cfile = info->file;
|
||||
strcat(strcpy(buf, path), "/*");
|
||||
info->dir = (void *)_findfirst(buf, cfile);
|
||||
info->name = cfile->name;
|
||||
be_os_free(buf);
|
||||
return (intptr_t)info->dir == -1;
|
||||
}
|
||||
be_os_free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// int be_dirnext(bdirinfo *info)
|
||||
// {
|
||||
// struct _finddata_t *cfile = info->file;
|
||||
// int res = _findnext((intptr_t)info->dir, cfile) != 0;
|
||||
// info->name = cfile->name;
|
||||
// return res;
|
||||
// }
|
||||
int be_dirnext(bdirinfo *info)
|
||||
{
|
||||
struct _finddata_t *cfile = info->file;
|
||||
int res = _findnext((intptr_t)info->dir, cfile) != 0;
|
||||
info->name = cfile->name;
|
||||
return res;
|
||||
}
|
||||
|
||||
// int be_dirclose(bdirinfo *info)
|
||||
// {
|
||||
// be_os_free(info->file);
|
||||
// return _findclose((intptr_t)info->dir) != 0;
|
||||
// }
|
||||
int be_dirclose(bdirinfo *info)
|
||||
{
|
||||
be_os_free(info->file);
|
||||
return _findclose((intptr_t)info->dir) != 0;
|
||||
}
|
||||
|
||||
// #else /* must be POSIX */
|
||||
#else /* must be POSIX */
|
||||
|
||||
// #include <dirent.h>
|
||||
// #include <unistd.h>
|
||||
// #include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
// int be_isdir(const char *path)
|
||||
// {
|
||||
// struct stat path_stat;
|
||||
// int res = stat(path, &path_stat);
|
||||
// return res == 0 && S_ISDIR(path_stat.st_mode);
|
||||
// }
|
||||
int be_isdir(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
int res = stat(path, &path_stat);
|
||||
return res == 0 && S_ISDIR(path_stat.st_mode);
|
||||
}
|
||||
|
||||
// int be_isfile(const char *path)
|
||||
// {
|
||||
// struct stat path_stat;
|
||||
// int res = stat(path, &path_stat);
|
||||
// return res == 0 && !S_ISDIR(path_stat.st_mode);
|
||||
// }
|
||||
int be_isfile(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
int res = stat(path, &path_stat);
|
||||
return res == 0 && !S_ISDIR(path_stat.st_mode);
|
||||
}
|
||||
|
||||
// int be_isexist(const char *path)
|
||||
// {
|
||||
// struct stat path_stat;
|
||||
// return stat(path, &path_stat) == 0;
|
||||
// }
|
||||
int be_isexist(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
return stat(path, &path_stat) == 0;
|
||||
}
|
||||
|
||||
// char* be_getcwd(char *buf, size_t size)
|
||||
// {
|
||||
// return getcwd(buf, size);
|
||||
// }
|
||||
char* be_getcwd(char *buf, size_t size)
|
||||
{
|
||||
return getcwd(buf, size);
|
||||
}
|
||||
|
||||
// int be_chdir(const char *path)
|
||||
// {
|
||||
// return chdir(path);
|
||||
// }
|
||||
int be_chdir(const char *path)
|
||||
{
|
||||
return chdir(path);
|
||||
}
|
||||
|
||||
// int be_mkdir(const char *path)
|
||||
// {
|
||||
// #ifdef _WIN32
|
||||
// return mkdir(path);
|
||||
// #else
|
||||
// return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
// #endif
|
||||
// }
|
||||
int be_mkdir(const char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return mkdir(path);
|
||||
#else
|
||||
return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
// int be_unlink(const char *filename)
|
||||
// {
|
||||
// return remove(filename);
|
||||
// }
|
||||
int be_unlink(const char *filename)
|
||||
{
|
||||
return remove(filename);
|
||||
}
|
||||
|
||||
// int be_dirfirst(bdirinfo *info, const char *path)
|
||||
// {
|
||||
// info->dir = opendir(path);
|
||||
// if (info->dir) {
|
||||
// return be_dirnext(info);
|
||||
// }
|
||||
// return 1;
|
||||
// }
|
||||
int be_dirfirst(bdirinfo *info, const char *path)
|
||||
{
|
||||
info->dir = opendir(path);
|
||||
if (info->dir) {
|
||||
return be_dirnext(info);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// int be_dirnext(bdirinfo *info)
|
||||
// {
|
||||
// struct dirent *file;
|
||||
// info->file = file = readdir(info->dir);
|
||||
// if (file) {
|
||||
// info->name = file->d_name;
|
||||
// return 0;
|
||||
// }
|
||||
// return 1;
|
||||
// }
|
||||
int be_dirnext(bdirinfo *info)
|
||||
{
|
||||
struct dirent *file;
|
||||
info->file = file = readdir(info->dir);
|
||||
if (file) {
|
||||
info->name = file->d_name;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// int be_dirclose(bdirinfo *info)
|
||||
// {
|
||||
// return closedir(info->dir) != 0;
|
||||
// }
|
||||
int be_dirclose(bdirinfo *info)
|
||||
{
|
||||
return closedir(info->dir) != 0;
|
||||
}
|
||||
|
||||
// #endif /* POSIX */
|
||||
// #endif /* BE_USE_OS_MODULE || BE_USE_FILE_SYSTEM */
|
||||
#endif /* POSIX */
|
||||
#endif /* BE_USE_OS_MODULE || BE_USE_FILE_SYSTEM */
|
||||
|
|
|
@ -38,7 +38,7 @@ extern "C" {
|
|||
* type when the value is 2.
|
||||
* Default: 2
|
||||
*/
|
||||
#define BE_INTGER_TYPE 1
|
||||
#define BE_INTGER_TYPE 1 // use long int = uint32_t
|
||||
|
||||
/* Macro: BE_USE_SINGLE_FLOAT
|
||||
* Select floating point precision.
|
||||
|
@ -47,7 +47,7 @@ extern "C" {
|
|||
* numbers.
|
||||
* Default: 0
|
||||
**/
|
||||
#define BE_USE_SINGLE_FLOAT 1
|
||||
#define BE_USE_SINGLE_FLOAT 1 // use `float` not `double`
|
||||
|
||||
/* Macro: BE_USE_PRECOMPILED_OBJECT
|
||||
* Use precompiled objects to avoid creating these objects at
|
||||
|
@ -118,14 +118,14 @@ extern "C" {
|
|||
* otherwise disable the feature.
|
||||
* Default: 1
|
||||
**/
|
||||
#define BE_USE_BYTECODE_SAVER 0
|
||||
#define BE_USE_BYTECODE_SAVER 1
|
||||
|
||||
/* Macro: BE_USE_BYTECODE_LOADER
|
||||
* Enable load bytecode from file when BE_USE_BYTECODE_LOADER is not 0,
|
||||
* otherwise disable the feature.
|
||||
* Default: 1
|
||||
**/
|
||||
#define BE_USE_BYTECODE_LOADER 0
|
||||
#define BE_USE_BYTECODE_LOADER 1
|
||||
|
||||
/* Macro: BE_USE_SHARED_LIB
|
||||
* Enable shared library when BE_USE_SHARED_LIB is not 0,
|
||||
|
@ -160,7 +160,7 @@ extern "C" {
|
|||
#define BE_USE_TIME_MODULE 0
|
||||
#define BE_USE_OS_MODULE 0
|
||||
#define BE_USE_SYS_MODULE 0
|
||||
#define BE_USE_DEBUG_MODULE 0
|
||||
#define BE_USE_DEBUG_MODULE 1
|
||||
#define BE_USE_GC_MODULE 1
|
||||
|
||||
/* Macro: BE_EXPLICIT_XXX
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import json import string
|
||||
tasmota = module("tasmota")
|
||||
def log(m) print(m) end
|
||||
|
||||
#######
|
||||
|
||||
def charsinstring(s,c)
|
||||
for i:0..size(s)-1
|
||||
for j:0..size(c)-1
|
||||
|
@ -32,17 +36,17 @@ tasmota._operators="=<>!|"
|
|||
# split the item when there is an operator, returns a list of (left,op,right)
|
||||
# ex: "Dimmer>50" -> ["Dimmer",tasmota_gt,"50"]
|
||||
tasmota.find_op = def (item)
|
||||
pos = charsinstring(item, tasmota._operators)
|
||||
var pos = charsinstring(item, tasmota._operators)
|
||||
if pos>=0
|
||||
op_split = string.split(item,pos)
|
||||
var op_split = string.split(item,pos)
|
||||
#print(op_split)
|
||||
op_left = op_split[0]
|
||||
op_rest = op_split[1]
|
||||
var op_left = op_split[0]
|
||||
var op_rest = op_split[1]
|
||||
# iterate through operators
|
||||
for op:tasmota._op
|
||||
if string.find(op_rest,op[0]) == 0
|
||||
op_func = op[1]
|
||||
op_right = string.split(op_rest,size(op[0]))[1]
|
||||
var op_func = op[1]
|
||||
var op_right = string.split(op_rest,size(op[0]))[1]
|
||||
return [op_left,op_func,op_right]
|
||||
end
|
||||
end
|
||||
|
@ -52,7 +56,7 @@ end
|
|||
|
||||
|
||||
def findkeyi(m,keyi)
|
||||
keyu=string.toupper(keyi)
|
||||
var keyu = string.toupper(keyi)
|
||||
if classof(m) == map
|
||||
for k:m.keys()
|
||||
if string.toupper(k)==keyu || keyi=='?'
|
||||
|
@ -64,9 +68,9 @@ end
|
|||
|
||||
|
||||
tasmota.try_rule = def (ev, rule, f)
|
||||
rl_list = tasmota.find_op(rule)
|
||||
e=ev
|
||||
rl=string.split(rl_list[0],'#')
|
||||
var rl_list = tasmota.find_op(rule)
|
||||
var e=ev
|
||||
var rl=string.split(rl_list[0],'#')
|
||||
for it:rl
|
||||
found=findkeyi(e,it)
|
||||
if found == nil
|
||||
|
@ -89,11 +93,11 @@ tasmota_rules={}
|
|||
tasmota.rule = def(pat,f) tasmota_rules[pat] = f end
|
||||
|
||||
tasmota.exec_rules = def (ev_json)
|
||||
ev = json.load(ev_json)
|
||||
var ev = json.load(ev_json)
|
||||
var ret = false
|
||||
if ev == nil
|
||||
log("ERROR, bad json: "+ev_json, 3)
|
||||
log('BRY: ERROR, bad json: '+ev_json, 3)
|
||||
end
|
||||
ret = false
|
||||
for r:tasmota_rules.keys()
|
||||
ret = tasmota.try_rule(ev,r,tasmota_rules[r]) || ret
|
||||
end
|
||||
|
|
|
@ -186,6 +186,11 @@ extern "C" {
|
|||
}
|
||||
}
|
||||
|
||||
// called as a replacement to Berry `print()`
|
||||
void berry_log(const char * berry_buf);
|
||||
void berry_log(const char * berry_buf) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("%s"), berry_buf);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Handlers for Berry calls and async
|
||||
|
@ -302,7 +307,7 @@ const char berry_prog[] PROGMEM =
|
|||
|
||||
// find a key in map, case insensitive, return actual key or nil if not found
|
||||
"def findkeyi(m,keyi) "
|
||||
"keyu=string.toupper(keyi) "
|
||||
"var keyu = string.toupper(keyi) "
|
||||
"if classof(m) == map "
|
||||
"for k:m.keys() "
|
||||
"if string.toupper(k)==keyu || keyi=='?' "
|
||||
|
@ -341,17 +346,17 @@ const char berry_prog[] PROGMEM =
|
|||
// # split the item when there is an operator, returns a list of (left,op,right)
|
||||
// # ex: "Dimmer>50" -> ["Dimmer",tasmota_gt,"50"]
|
||||
"tasmota.find_op = def (item) "
|
||||
"pos = charsinstring(item, tasmota._operators) "
|
||||
"var pos = charsinstring(item, tasmota._operators) "
|
||||
"if pos>=0 "
|
||||
"op_split = string.split(item,pos) "
|
||||
"var op_split = string.split(item,pos) "
|
||||
// #print(op_split)
|
||||
"op_left = op_split[0] "
|
||||
"op_rest = op_split[1] "
|
||||
"var op_left = op_split[0] "
|
||||
"var op_rest = op_split[1] "
|
||||
// # iterate through operators
|
||||
"for op:tasmota._op "
|
||||
"if string.find(op_rest,op[0]) == 0 "
|
||||
"op_func = op[1] "
|
||||
"op_right = string.split(op_rest,size(op[0]))[1] "
|
||||
"var op_func = op[1] "
|
||||
"var op_right = string.split(op_rest,size(op[0]))[1] "
|
||||
"return [op_left,op_func,op_right] "
|
||||
"end "
|
||||
"end "
|
||||
|
@ -362,9 +367,9 @@ const char berry_prog[] PROGMEM =
|
|||
// Rules trigger if match. return true if match, false if not
|
||||
// Note: condition is not yet managed
|
||||
"tasmota.try_rule = def (ev, rule, f) "
|
||||
"rl_list = tasmota.find_op(rule) "
|
||||
"e=ev "
|
||||
"rl=string.split(rl_list[0],'#') "
|
||||
"var rl_list = tasmota.find_op(rule) "
|
||||
"var e=ev "
|
||||
"var rl=string.split(rl_list[0],'#') "
|
||||
"for it:rl "
|
||||
"found=findkeyi(e,it) "
|
||||
"if found == nil "
|
||||
|
@ -386,8 +391,8 @@ const char berry_prog[] PROGMEM =
|
|||
// Run rules, i.e. check each individual rule
|
||||
// Returns true if at least one rule matched, false if none
|
||||
"tasmota.exec_rules = def (ev_json) "
|
||||
"ev = json.load(ev_json) "
|
||||
"ret = false "
|
||||
"var ev = json.load(ev_json) "
|
||||
"var ret = false "
|
||||
"if ev == nil "
|
||||
"log('BRY: ERROR, bad json: '+ev_json, 3) "
|
||||
"end "
|
||||
|
@ -404,7 +409,7 @@ const char berry_prog[] PROGMEM =
|
|||
"tasmota.timer = def (delay,f) tasmota_timers.push([tasmota.millis(delay),f]) end "
|
||||
|
||||
"def _run_deferred() "
|
||||
"i=0 "
|
||||
"var i=0 "
|
||||
"while i<tasmota_timers.size() "
|
||||
"if tasmota.timereached(tasmota_timers[i][0]) "
|
||||
"f=tasmota_timers[i][1] "
|
||||
|
@ -418,12 +423,15 @@ const char berry_prog[] PROGMEM =
|
|||
|
||||
// Delay function, internally calls yield() every 10ms to avoid WDT
|
||||
"tasmota.delay = def(ms) "
|
||||
"tend = tasmota.millis(ms) "
|
||||
"var tend = tasmota.millis(ms) "
|
||||
"while !tasmota.timereached(tend) "
|
||||
"tasmota.yield() "
|
||||
"end "
|
||||
"end "
|
||||
|
||||
// try to load "/autoexec.be"
|
||||
// "try compile('/autoexec.be','file')() except .. log('BRY: no /autoexec.bat file') end "
|
||||
|
||||
// trigger Garbage Collector
|
||||
"gc.collect() "
|
||||
;
|
||||
|
|
Loading…
Reference in New Issue