feat(lua): add lua_module_system

This commit is contained in:
zhouli
2026-04-18 18:56:23 +08:00
parent 2c40c19202
commit adeffc575b
8 changed files with 451 additions and 0 deletions
@@ -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);
}