mirror of
https://github.com/m5stack/ESP-Claw.git
synced 2026-05-20 11:51:49 -07:00
feat(lua): add lua_module_system
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"src/lua_module_system.c"
|
||||
INCLUDE_DIRS
|
||||
"include"
|
||||
REQUIRES
|
||||
cap_lua
|
||||
esp_timer
|
||||
esp_wifi
|
||||
heap
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "lua.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int luaopen_system(lua_State *L);
|
||||
esp_err_t lua_module_system_register(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
# Lua System
|
||||
|
||||
This skill describes how to correctly use system when writing Lua scripts.
|
||||
|
||||
## How to call
|
||||
- Import it with `local system = require("system")`
|
||||
- This module does not require manual initialization after `require`
|
||||
|
||||
## API
|
||||
|
||||
### `system.time()`
|
||||
- Inputs: none
|
||||
- Output: `number`
|
||||
- Returns the current Unix timestamp in seconds
|
||||
- Raises an error if the system clock is not set
|
||||
|
||||
### `system.date(format)`
|
||||
- Inputs:
|
||||
- `format`: optional `string`, defaults to `"%Y-%m-%d %H:%M:%S"`
|
||||
- Output: `string`
|
||||
- Returns the formatted local time string using `strftime`-style placeholders
|
||||
- Raises an error if the format is too long or produces an empty string
|
||||
|
||||
### `system.millis()`
|
||||
- Inputs: none
|
||||
- Output: `number`
|
||||
- Returns the device uptime in milliseconds
|
||||
|
||||
### `system.uptime()`
|
||||
- Inputs: none
|
||||
- Output: `integer`
|
||||
- Returns the device uptime in seconds
|
||||
|
||||
### `system.info()`
|
||||
- Inputs: none
|
||||
- Output: `table`
|
||||
- Returns a table with these possible fields:
|
||||
- `uptime_s`: `integer`, uptime in seconds
|
||||
- `time`: `number`, current Unix timestamp in seconds
|
||||
- `date`: `string`, formatted local time as `%Y-%m-%d %H:%M:%S`
|
||||
- `sram_free`: `integer`, free internal SRAM bytes
|
||||
- `sram_total`: `integer`, total internal SRAM bytes
|
||||
- `sram_largest`: `integer`, largest free internal SRAM block in bytes
|
||||
- `psram_free`: `integer`, free PSRAM bytes, present only when PSRAM exists
|
||||
- `psram_total`: `integer`, total PSRAM bytes, present only when PSRAM exists
|
||||
- `wifi_rssi`: `integer`, connected AP RSSI, present only when Wi-Fi STA is connected
|
||||
- `wifi_ssid`: `string`, connected AP SSID, present only when available
|
||||
|
||||
## Example
|
||||
```lua
|
||||
local system = require("system")
|
||||
|
||||
print(system.time())
|
||||
print(system.date("%Y-%m-%d %H:%M:%S"))
|
||||
print(system.millis())
|
||||
print(system.uptime())
|
||||
|
||||
local info = system.info()
|
||||
print(info.sram_free)
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"skills": [
|
||||
{
|
||||
"id": "lua_module_system",
|
||||
"file": "lua_module_system.md",
|
||||
"title": "lua_module_system",
|
||||
"summary": "How to access time, uptime, memory, and Wi-Fi info from Lua through the system module.",
|
||||
"cap_groups": [
|
||||
"cap_lua"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "lua_module_system.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "cap_lua.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "lauxlib.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static void lua_module_system_ensure_tz(void)
|
||||
{
|
||||
setenv("TZ", CONFIG_BASIC_DEMO_TIME_TIMEZONE, 1);
|
||||
tzset();
|
||||
}
|
||||
|
||||
static int lua_module_system_time(lua_State *L)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
lua_module_system_ensure_tz();
|
||||
now = time(NULL);
|
||||
if (now < 0) {
|
||||
return luaL_error(L, "system clock not set");
|
||||
}
|
||||
|
||||
lua_pushnumber(L, (lua_Number)now);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_module_system_date(lua_State *L)
|
||||
{
|
||||
const char *fmt = luaL_optstring(L, 1, "%Y-%m-%d %H:%M:%S");
|
||||
char buf[128];
|
||||
struct tm local_time;
|
||||
time_t now;
|
||||
size_t len;
|
||||
|
||||
lua_module_system_ensure_tz();
|
||||
now = time(NULL);
|
||||
localtime_r(&now, &local_time);
|
||||
|
||||
len = strftime(buf, sizeof(buf), fmt, &local_time);
|
||||
if (len == 0) {
|
||||
return luaL_error(L, "system.date: format too long or produced empty string");
|
||||
}
|
||||
|
||||
lua_pushstring(L, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_module_system_millis(lua_State *L)
|
||||
{
|
||||
int64_t us = esp_timer_get_time();
|
||||
|
||||
lua_pushnumber(L, (lua_Number)(us / 1000));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_module_system_uptime(lua_State *L)
|
||||
{
|
||||
int64_t us = esp_timer_get_time();
|
||||
|
||||
lua_pushinteger(L, (lua_Integer)(us / 1000000));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_module_system_info(lua_State *L)
|
||||
{
|
||||
char date_buf[32];
|
||||
struct tm local_time;
|
||||
time_t now;
|
||||
size_t psram_total;
|
||||
wifi_ap_record_t ap_info = {0};
|
||||
int64_t us;
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
us = esp_timer_get_time();
|
||||
lua_pushinteger(L, (lua_Integer)(us / 1000000));
|
||||
lua_setfield(L, -2, "uptime_s");
|
||||
|
||||
lua_module_system_ensure_tz();
|
||||
now = time(NULL);
|
||||
lua_pushnumber(L, (lua_Number)now);
|
||||
lua_setfield(L, -2, "time");
|
||||
|
||||
localtime_r(&now, &local_time);
|
||||
if (strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &local_time) > 0) {
|
||||
lua_pushstring(L, date_buf);
|
||||
lua_setfield(L, -2, "date");
|
||||
}
|
||||
|
||||
lua_pushinteger(L, (lua_Integer)heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
||||
lua_setfield(L, -2, "sram_free");
|
||||
|
||||
lua_pushinteger(L, (lua_Integer)heap_caps_get_total_size(MALLOC_CAP_INTERNAL));
|
||||
lua_setfield(L, -2, "sram_total");
|
||||
|
||||
lua_pushinteger(L, (lua_Integer)heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
|
||||
lua_setfield(L, -2, "sram_largest");
|
||||
|
||||
psram_total = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
|
||||
if (psram_total > 0) {
|
||||
lua_pushinteger(L, (lua_Integer)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
lua_setfield(L, -2, "psram_free");
|
||||
|
||||
lua_pushinteger(L, (lua_Integer)psram_total);
|
||||
lua_setfield(L, -2, "psram_total");
|
||||
}
|
||||
|
||||
if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) {
|
||||
lua_pushinteger(L, (lua_Integer)ap_info.rssi);
|
||||
lua_setfield(L, -2, "wifi_rssi");
|
||||
|
||||
if (ap_info.ssid[0] != '\0') {
|
||||
lua_pushstring(L, (const char *)ap_info.ssid);
|
||||
lua_setfield(L, -2, "wifi_ssid");
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int luaopen_system(lua_State *L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushcfunction(L, lua_module_system_time);
|
||||
lua_setfield(L, -2, "time");
|
||||
|
||||
lua_pushcfunction(L, lua_module_system_date);
|
||||
lua_setfield(L, -2, "date");
|
||||
|
||||
lua_pushcfunction(L, lua_module_system_millis);
|
||||
lua_setfield(L, -2, "millis");
|
||||
|
||||
lua_pushcfunction(L, lua_module_system_uptime);
|
||||
lua_setfield(L, -2, "uptime");
|
||||
|
||||
lua_pushcfunction(L, lua_module_system_info);
|
||||
lua_setfield(L, -2, "info");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t lua_module_system_register(void)
|
||||
{
|
||||
return cap_lua_register_module("system", luaopen_system);
|
||||
}
|
||||
Reference in New Issue
Block a user