更新
This commit is contained in:
parent
2260db4cfb
commit
76605d1d61
BIN
air780e/core/LuatOS-SoC_V1109_EC618.soc
Normal file
BIN
air780e/core/LuatOS-SoC_V1109_EC618.soc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
air780e/core/SOC量产及远程升级文件/EC618/output.sota
Normal file
BIN
air780e/core/SOC量产及远程升级文件/EC618/output.sota
Normal file
Binary file not shown.
@ -1,6 +1,9 @@
|
||||
return {
|
||||
NOTIFY_TYPE = "uart",
|
||||
-- DINGTALK_WEBHOOK = "",
|
||||
|
||||
UART_ID = 1,
|
||||
STATUS_GPIO = 1,
|
||||
--
|
||||
-- 定时查询流量间隔, 单位毫秒, 设置为 0 关闭 (建议检查 util_mobile.lua 文件中运营商号码和查询代码是否正确, 以免发错短信导致扣费, 收到查询结果短信发送通知会消耗流量)
|
||||
QUERY_TRAFFIC_INTERVAL = 0,
|
||||
@ -15,7 +18,7 @@ return {
|
||||
NOTIFY_APPEND_MORE_INFO = true,
|
||||
--
|
||||
-- 通知最大重发次数
|
||||
NOTIFY_RETRY_MAX = 20,
|
||||
NOTIFY_RETRY_MAX = 50,
|
||||
--
|
||||
-- 开启低功耗模式, USB 断开连接无法查看日志, RNDIS 网卡会断开
|
||||
LOW_POWER_MODE = false,
|
@ -13,24 +13,16 @@ require "sysplus"
|
||||
wdt.init(9000)
|
||||
sys.timerLoopStart(wdt.feed, 3000)
|
||||
|
||||
-- 设置 DNS
|
||||
socket.setDNS(nil, 1, "119.29.29.29")
|
||||
socket.setDNS(nil, 2, "223.5.5.5")
|
||||
|
||||
-- 设置 SIM 自动恢复(单位: 毫秒), 搜索小区信息间隔(单位: 毫秒), 最大搜索时间(单位: 秒)
|
||||
mobile.setAuto(1000 * 10)
|
||||
|
||||
-- 开启 IPv6
|
||||
-- mobile.ipv6(true)
|
||||
|
||||
-- POWERKEY
|
||||
local button_last_press_time, button_last_release_time = 0, 0
|
||||
gpio.setup(
|
||||
35,
|
||||
10,
|
||||
function()
|
||||
local current_time = mcu.ticks()
|
||||
-- 按下
|
||||
if gpio.get(35) == 0 then
|
||||
if gpio.get(10) == gpio.LOW then
|
||||
button_last_press_time = current_time -- 记录最后一次按下时间
|
||||
return
|
||||
end
|
||||
@ -62,6 +54,8 @@ util_mobile = require "util_mobile"
|
||||
-- util_location = require "util_location"
|
||||
util_notify = require "util_notify"
|
||||
|
||||
-- 传输状态机 GPIO1 默认低 内部下拉
|
||||
gpio.setup(config.STATUS_GPIO, nil, gpio.PULLDOWN)
|
||||
-- 短信接收回调
|
||||
sms.setNewSmsCb(
|
||||
function(sender_number, sms_content, m)
|
||||
@ -76,60 +70,119 @@ sms.setNewSmsCb(
|
||||
sms.send(receiver_number, sms_content_to_be_sent)
|
||||
is_sms_ctrl = true
|
||||
end
|
||||
local my_number = mobile.number(mobile.simid())
|
||||
-- local my_number = mobile.number(mobile.simid())
|
||||
-- 发送通知
|
||||
util_notify.add(
|
||||
{
|
||||
"#" .. string.gsub(my_number,"+86","",1) .. "收到短信来自" .. sender_number,
|
||||
"",
|
||||
sms_content,
|
||||
"",
|
||||
"发件时间: " .. time,
|
||||
"短信状态: " .. (is_sms_ctrl and "控制" or "正常")
|
||||
from = sender_number,
|
||||
sms = sms_content,
|
||||
from_time = time,
|
||||
sms_type = (is_sms_ctrl and "控制" or "正常"),
|
||||
type = "sms"
|
||||
}
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
old_ststus = ""
|
||||
sys.taskInit(
|
||||
function()
|
||||
-- 等待网络环境准备就绪
|
||||
sys.waitUntil("IP_READY")
|
||||
|
||||
util_netled.init()
|
||||
|
||||
-- 开机通知
|
||||
if config.BOOT_NOTIFY then
|
||||
util_notify.add("#开机通知")
|
||||
util_notify.add(
|
||||
{
|
||||
sms = "设备开机",
|
||||
type = "boot"
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
-- 等待网络环境准备就绪
|
||||
-- sys.waitUntil("IP_READY")
|
||||
sys.subscribe("IP_READY", function()
|
||||
log.info("main", "IP_READY")
|
||||
end)
|
||||
-- 定时查询流量
|
||||
if config.QUERY_TRAFFIC_INTERVAL and config.QUERY_TRAFFIC_INTERVAL >= 1000 * 60 then
|
||||
sys.timerLoopStart(util_mobile.queryTraffic, config.QUERY_TRAFFIC_INTERVAL)
|
||||
end
|
||||
-- if config.QUERY_TRAFFIC_INTERVAL and config.QUERY_TRAFFIC_INTERVAL >= 1000 * 60 then
|
||||
-- sys.timerLoopStart(util_mobile.queryTraffic, config.QUERY_TRAFFIC_INTERVAL)
|
||||
-- end
|
||||
|
||||
-- -- 定时基站定位
|
||||
-- if config.LOCATION_INTERVAL and config.LOCATION_INTERVAL >= 1000 * 30 then
|
||||
-- sys.timerLoopStart(util_location.refresh, config.LOCATION_INTERVAL, 30)
|
||||
-- end
|
||||
-- 断网后会发一次这个消息
|
||||
sys.subscribe("SIM_IND", function(status, value)
|
||||
-- log.info("上次状态", old_ststus,"当前状态",status,old_ststus ~= string.gsub(status, "%s+", ""))
|
||||
if old_ststus ~= string.gsub(status, "%s+", "") then
|
||||
old_ststus = string.gsub(status, "%s+", "")
|
||||
-- status的取值有:
|
||||
-- RDY SIM卡就绪, value为nil
|
||||
-- NORDY 无SIM卡, value为nil
|
||||
-- SIM_PIN 需要输入PIN, value为nil
|
||||
-- GET_NUMBER 获取到电话号码(不一定有值), value为nil
|
||||
-- SIM_WC SIM卡的写入次数统计,掉电归0, value为统计值
|
||||
if status == "RDY" then
|
||||
log.info("main", "SIM卡就绪")
|
||||
elseif status == "NORDY" then
|
||||
log.info("main", "无SIM卡")
|
||||
util_notify.add(
|
||||
{
|
||||
sms = "设备没安装SIM卡",
|
||||
type = "boot"
|
||||
}
|
||||
)
|
||||
elseif status == "SIM_PIN" then
|
||||
log.info("main", "需要输入PIN")
|
||||
util_notify.add(
|
||||
{
|
||||
sms = "设备SIM卡需要输入PIN码解锁",
|
||||
type = "boot"
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- 电源键短按发送测试通知
|
||||
sys.subscribe(
|
||||
"POWERKEY_SHORT_PRESS",
|
||||
function()
|
||||
util_notify.add("#ALIVE")
|
||||
log.info("main", "POWERKEY_SHORT_PRESS")
|
||||
util_notify.add(
|
||||
{
|
||||
from = "15264925507",
|
||||
sms = "本地测试短信通知并没有实际收到短信",
|
||||
from_time = "2024-03-14 00:00:00",
|
||||
sms_type = "正常",
|
||||
type = "sms"
|
||||
}
|
||||
)
|
||||
end
|
||||
)
|
||||
-- 电源键长按查询流量
|
||||
sys.subscribe("POWERKEY_LONG_PRESS", util_mobile.queryTraffic)
|
||||
sys.subscribe(
|
||||
"POWERKEY_LONG_PRESS",
|
||||
function()
|
||||
log.info("main", "POWERKEY_LONG_PRESS")
|
||||
util_notify.add(
|
||||
{
|
||||
from = "15264925507",
|
||||
sms = "长按本地测试短信通知并没有实际收到短信",
|
||||
from_time = "2024-03-14 00:00:00",
|
||||
sms_type = "正常",
|
||||
type = "sms"
|
||||
}
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
-- 开启低功耗模式
|
||||
if config.LOW_POWER_MODE then
|
||||
sys.wait(1000 * 15)
|
||||
log.warn("main", "即将关闭 usb 电源, 如需查看日志请在配置中关闭低功耗模式")
|
||||
sys.wait(1000 * 5)
|
||||
gpio.setup(23, nil)
|
||||
gpio.close(33)
|
||||
-- gpio.setup(23, nil)
|
||||
-- gpio.close(33)
|
||||
pm.power(pm.USB, false) -- 关闭 USB
|
||||
pm.power(pm.GPS, false)
|
||||
pm.power(pm.GPS_ANT, false)
|
@ -28,7 +28,7 @@ local notify = {
|
||||
local res_body = uart.write(config.UART_ID, msg)
|
||||
return 200, '', res_body
|
||||
end,
|
||||
-- -- 发送到 dingtalk
|
||||
-- 发送到 dingtalk
|
||||
-- ["dingtalk"] = function(msg)
|
||||
-- if config.DINGTALK_WEBHOOK == nil or config.DINGTALK_WEBHOOK == "" then
|
||||
-- log.error("util_notify", "未配置 `config.DINGTALK_WEBHOOK`")
|
||||
@ -76,14 +76,15 @@ local notify = {
|
||||
-- end,
|
||||
}
|
||||
|
||||
local function append()
|
||||
local msg = "\n"
|
||||
|
||||
local function append(msg)
|
||||
if type(msg) ~= "table" then
|
||||
log.error("util_notify.append", "添加扩展信息错误", "参数类型错误", type(msg))
|
||||
return msg
|
||||
end
|
||||
-- 本机号码
|
||||
local my_number = mobile.number(mobile.simid())
|
||||
local number = string.gsub(my_number,"+86","",1)
|
||||
local number = mobile.number(mobile.simid())
|
||||
if number then
|
||||
msg = msg .. "\n本机号码: " .. number
|
||||
msg.to = string.gsub(number,"+86","",1)
|
||||
end
|
||||
|
||||
-- 开机时长
|
||||
@ -95,50 +96,21 @@ local function append()
|
||||
minutes = minutes % 60
|
||||
local boot_time = string.format("%02d:%02d:%02d", hours, minutes, seconds)
|
||||
if ms >= 0 then
|
||||
msg = msg .. "\n开机时长: " .. boot_time
|
||||
msg.start_time = boot_time
|
||||
end
|
||||
|
||||
-- 运营商
|
||||
local oper = util_mobile.getOper(true)
|
||||
if oper ~= "" then
|
||||
msg = msg .. "\n运营商: " .. oper
|
||||
msg.oper = oper
|
||||
end
|
||||
|
||||
-- 信号
|
||||
local rsrp = mobile.rsrp()
|
||||
if rsrp ~= 0 then
|
||||
msg = msg .. "\n信号: " .. rsrp .. "dBm"
|
||||
msg.rsrp = rsrp
|
||||
end
|
||||
|
||||
-- -- 频段
|
||||
-- local band = util_mobile.getBand()
|
||||
-- if band >= 0 then
|
||||
-- msg = msg .. "\n频段: B" .. band
|
||||
-- end
|
||||
|
||||
-- 流量统计
|
||||
-- local uplinkGB, uplinkB, downlinkGB, downlinkB = mobile.dataTraffic()
|
||||
-- uplinkB = uplinkGB * 1024 * 1024 * 1024 + uplinkB
|
||||
-- downlinkB = downlinkGB * 1024 * 1024 * 1024 + downlinkB
|
||||
-- local function formatBytes(bytes)
|
||||
-- if bytes < 1024 then
|
||||
-- return bytes .. "B"
|
||||
-- elseif bytes < 1024 * 1024 then
|
||||
-- return string.format("%.2fKB", bytes / 1024)
|
||||
-- elseif bytes < 1024 * 1024 * 1024 then
|
||||
-- return string.format("%.2fMB", bytes / 1024 / 1024)
|
||||
-- else
|
||||
-- return string.format("%.2fGB", bytes / 1024 / 1024 / 1024)
|
||||
-- end
|
||||
-- end
|
||||
-- msg = msg .. "\n流量: ↑" .. formatBytes(uplinkB) .. " ↓" .. formatBytes(downlinkB)
|
||||
|
||||
-- 位置
|
||||
-- local _, _, map_link = util_location.get()
|
||||
-- if map_link ~= "" then
|
||||
-- msg = msg .. "\n位置: " .. map_link -- 这里使用 U+00a0 防止换行
|
||||
-- end
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
@ -150,12 +122,12 @@ function util_notify.send(msg, channel)
|
||||
log.info("util_notify.send", "发送通知", channel)
|
||||
|
||||
-- 判断消息内容 msg
|
||||
if type(msg) ~= "string" then
|
||||
if type(msg) ~= "table" then
|
||||
log.error("util_notify.send", "发送通知失败", "参数类型错误", type(msg))
|
||||
return true
|
||||
end
|
||||
if msg == "" then
|
||||
log.error("util_notify.send", "发送通知失败", "消息为空")
|
||||
if msg.sms == "" then
|
||||
log.error("util_notify.send", "发送通知失败", "消息内容为空")
|
||||
return true
|
||||
end
|
||||
|
||||
@ -167,11 +139,11 @@ function util_notify.send(msg, channel)
|
||||
|
||||
-- 通知内容追加更多信息
|
||||
if config.NOTIFY_APPEND_MORE_INFO then
|
||||
msg = msg .. append()
|
||||
msg = append(msg)
|
||||
end
|
||||
|
||||
-- 发送通知
|
||||
local code, headers, body = notify[channel](msg)
|
||||
local code, headers, body = notify[channel](json.encode(msg))
|
||||
if code == nil then
|
||||
log.info("util_notify.send", "发送通知失败, 无需重发", "code:", code, "body:", body)
|
||||
return true
|
||||
@ -182,9 +154,6 @@ function util_notify.send(msg, channel)
|
||||
return true
|
||||
end
|
||||
if code >= 200 and code < 500 then
|
||||
-- http 2xx 成功
|
||||
-- http 3xx 重定向, 重发也不会成功
|
||||
-- http 4xx 客户端错误, 重发也不会成功
|
||||
log.info("util_notify.send", "发送通知成功", "code:", code, "body:", body)
|
||||
return true
|
||||
end
|
||||
@ -196,16 +165,13 @@ end
|
||||
-- @param msg 消息内容
|
||||
-- @param channels 通知渠道
|
||||
function util_notify.add(msg, channels)
|
||||
if type(msg) == "table" then
|
||||
msg = table.concat(msg, "\n")
|
||||
if type(msg) ~= "table" then
|
||||
log.info("util_notify.add", "添加消息失败", "参数错误")
|
||||
end
|
||||
|
||||
channels = channels or config.NOTIFY_TYPE
|
||||
|
||||
if type(channels) ~= "table" then
|
||||
channels = {channels}
|
||||
end
|
||||
|
||||
for _, channel in ipairs(channels) do
|
||||
table.insert(msg_queue, {channel = channel, msg = msg, retry = 0})
|
||||
end
|
||||
@ -220,25 +186,29 @@ local function poll()
|
||||
local item, result
|
||||
while true do
|
||||
-- 消息队列非空, 且网络已注册
|
||||
if next(msg_queue) ~= nil and mobile.status() == 1 then
|
||||
log.debug("util_notify.poll", "轮询消息队列中, 当前队列长度:", #msg_queue)
|
||||
|
||||
item = msg_queue[1]
|
||||
table.remove(msg_queue, 1)
|
||||
|
||||
if item.retry > (config.NOTIFY_RETRY_MAX or 100) then
|
||||
log.error("util_notify.poll", "超过最大重发次数", "msg:", item.msg)
|
||||
else
|
||||
result = util_notify.send(item.msg, item.channel)
|
||||
item.retry = item.retry + 1
|
||||
|
||||
if not result then
|
||||
-- 发送失败, 移到队尾
|
||||
table.insert(msg_queue, item)
|
||||
sys.wait(5000)
|
||||
if next(msg_queue) ~= nil then
|
||||
-- log.debug("util_notify.poll等待信号",gpio.get(config.STATUS_GPIO),gpio.HIGH)
|
||||
if gpio.get(config.STATUS_GPIO) == gpio.HIGH then
|
||||
log.debug("util_notify.poll", "轮询消息队列中, 当前队列长度:", #msg_queue)
|
||||
item = msg_queue[1]
|
||||
table.remove(msg_queue, 1)
|
||||
if item.retry > (config.NOTIFY_RETRY_MAX or 100) then
|
||||
log.error("util_notify.poll", "超过最大重发次数", "消息内容:", json.encode(item.msg))
|
||||
else
|
||||
result = util_notify.send(item.msg, item.channel)
|
||||
item.retry = item.retry + 1
|
||||
if not result then
|
||||
-- 发送失败, 移到队尾
|
||||
table.insert(msg_queue, item)
|
||||
sys.wait(50)
|
||||
end
|
||||
sys.wait(1000)
|
||||
end
|
||||
sys.wait(50)
|
||||
else
|
||||
-- log.debug("util_notify.poll", "等待主机状态下发, 当前队列长度:", #msg_queue)
|
||||
sys.wait(50)
|
||||
end
|
||||
sys.wait(50)
|
||||
else
|
||||
sys.waitUntil("NEW_MSG", 1000 * 10)
|
||||
end
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
esp32c3/core/LuatOS-SoC_V1007_ESP32C3_USB.soc
Normal file
BIN
esp32c3/core/LuatOS-SoC_V1007_ESP32C3_USB.soc
Normal file
Binary file not shown.
129
esp32c3/script/air780_helper.lua
Normal file
129
esp32c3/script/air780_helper.lua
Normal file
@ -0,0 +1,129 @@
|
||||
local air780_helper = {
|
||||
-- 是否正在读取串口数据
|
||||
}
|
||||
air780_helper.reading = false
|
||||
air780_helper.cs_index = 1
|
||||
local sys = require("sys")
|
||||
local utils = require("utils")
|
||||
local config = require("config")
|
||||
local util_notify = require("util_notify")
|
||||
|
||||
local uart_timeout = 100
|
||||
|
||||
|
||||
-- 使用UART 1接口与Air780E通信
|
||||
-- ESP32 <--> Air780E
|
||||
-- 02(UART1_TX) <--> 31(UART1_RXD)
|
||||
-- 03(UART1_RX) <--> 30(UART1_TXD)
|
||||
local uart_setup_result = uart.setup(config.UART_ID, 115200, 8, 1)
|
||||
if uart_setup_result ~= 0 then
|
||||
log.error("air780_helper", "UART初始化失败,返回值:"..uart_setup_result..",ESP32将重启")
|
||||
sys.wait(1000)
|
||||
rtos.reboot()
|
||||
else
|
||||
log.info("air780_helper", "UART初始化成功")
|
||||
end
|
||||
|
||||
-- 串口读缓冲区
|
||||
local send_queue = {}
|
||||
|
||||
-- 注册串口接收事件回调
|
||||
uart.on(config.UART_ID, "receive", function(id, length)
|
||||
air780_helper.reading = true
|
||||
local s = ""
|
||||
repeat
|
||||
-- log.error("air780_helper", "开始设备串口")
|
||||
s = uart.read(id, length)
|
||||
if #s > 0 then
|
||||
table.insert(send_queue, s)
|
||||
sys.timerStart(sys.publish, config.UART_TIMEOUT, "UART_READY")
|
||||
-- sys.publish("UART_READY")
|
||||
end
|
||||
until s == ""
|
||||
end)
|
||||
|
||||
sys.subscribe("UART_READY", function()
|
||||
led_helper.shut_working_led()
|
||||
led_helper.blink_status_led(config.LED_BLINK_DURATION.initializing)
|
||||
-- 拼接所有收到的数据
|
||||
local data = table.concat(send_queue)
|
||||
log.info("air780_helper", '读取短信完成',data)
|
||||
-- 读取完成后清空缓冲区
|
||||
utils.clear_table(send_queue)
|
||||
air780_helper.reading = false
|
||||
log.info("air780_helper", "去NEW_MSG处理消息类型和内容")
|
||||
sys.publish("NEW_MSG",data)
|
||||
|
||||
-- while #data > 0 do
|
||||
-- air780_helper.reading = false
|
||||
-- sys.publish(config.UART_NEW_MSG,data)
|
||||
-- end
|
||||
end)
|
||||
|
||||
-- 收到串口新消息 添加到发送队列
|
||||
sys.subscribe("NEW_MSG", function(data)
|
||||
if data == nil then
|
||||
return
|
||||
end
|
||||
if #data == 0 then
|
||||
return
|
||||
end
|
||||
local msg = json.decode(data)
|
||||
if utils.table_len(msg) <= 0 then
|
||||
return
|
||||
end
|
||||
if msg == nil then
|
||||
return
|
||||
end
|
||||
local numbers = fskv.kv_get("numbers")
|
||||
-- log.info("air780_helper", "测试numbers", json.encode(numbers),type(numbers))
|
||||
local cs_index = air780_helper.cs_index - 1
|
||||
if utils.is_empty(msg.sms) == false then
|
||||
air780_helper.reading = false
|
||||
msg.index = tostring(cs_index)
|
||||
-- 是否屏蔽自检信息
|
||||
local disable_boot = fskv.kv_get("disable_boot")
|
||||
if disable_boot == 1 and msg.type == "boot" then
|
||||
return
|
||||
end
|
||||
-- 如果没有读到号码就是用设置的号码
|
||||
if utils.is_empty(msg.to) then
|
||||
if fskv.kv_get("numbers") then
|
||||
if numbers[cs_index] ~= nil then
|
||||
msg.to = numbers[cs_index]
|
||||
end
|
||||
end
|
||||
end
|
||||
if fskv.kv_get("hostname") then
|
||||
msg.hostname = fskv.kv_get("hostname")
|
||||
else
|
||||
msg.hostname = "weiguo_" .. wlan.getMac()
|
||||
end
|
||||
if utils.is_empty(msg.from) and msg.type == "boot" then
|
||||
msg.from = nil
|
||||
msg.sms = "收到设备通知:" .. msg.sms
|
||||
msg.index = nil
|
||||
end
|
||||
util_notify.add(msg)
|
||||
utils.clear_table(msg)
|
||||
msg = nil
|
||||
end
|
||||
end)
|
||||
-- 发送AT指令
|
||||
function air780_helper.send_at_command(command)
|
||||
uart.write(config.UART_ID, command)
|
||||
uart.write(config.UART_ID, "\r\n")
|
||||
log.debug("air780_helper", "发送AT指令\""..command.."\"")
|
||||
end
|
||||
-- 发送AT指令并等待指定topic
|
||||
function air780_helper.send_at_command_and_wait(command, topic_listen_to, timeout)
|
||||
while true do
|
||||
air780_helper.send_at_command(command)
|
||||
local is_successful, r1, r2, r3 = sys.waitUntil(topic_listen_to, timeout or 1000)
|
||||
if is_successful then
|
||||
return r1, r2, r3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return air780_helper
|
42
esp32c3/script/config.lua
Normal file
42
esp32c3/script/config.lua
Normal file
@ -0,0 +1,42 @@
|
||||
return {
|
||||
-- 轮询间隔
|
||||
POLL_INTERVAL = 3000,
|
||||
UART_ID = 1,
|
||||
-- 串口读取延时 毫秒
|
||||
UART_TIMEOUT = 500,
|
||||
-- 设备选择用GPIO 对应5个子设备 默认下拉
|
||||
CS_GPIO = {2,3,10,6,7},
|
||||
DNS_SERVERS = {
|
||||
"114.114.114.114",
|
||||
"223.5.5.5",
|
||||
"8.8.8.8",
|
||||
"1.1.1.1"
|
||||
},
|
||||
LOG_LEVEL = log.LOG_INFO,
|
||||
-- LED针脚
|
||||
LED = {
|
||||
LED_A = 12,
|
||||
LED_B = 13
|
||||
},
|
||||
-- LED闪烁间隔
|
||||
LED_BLINK_DURATION = {
|
||||
working = 50,
|
||||
initializing = 500
|
||||
},
|
||||
-- 通知最大重发次数
|
||||
NOTIFY_RETRY_MAX = 50,
|
||||
-- 通知配置 ========================================
|
||||
NOTIFY_TYPE = {
|
||||
"dingtalk",
|
||||
"wecom"
|
||||
},
|
||||
NOTIFY_CHANNEL = {
|
||||
-- 钉钉机器人的webhook地址
|
||||
DINGTALK_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=a6927dc518beeec0fe75e355e4e5cf42f1671e25741ce9da2904d3ed1432da85",
|
||||
-- 企业微信机器人的webhook地址
|
||||
WECOM_WEBHOOK = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=89564a1c-50d4-4dea-b3f7-511c3213ade7",
|
||||
-- inotify推送地址
|
||||
INOTIFY_URL = "",
|
||||
}
|
||||
|
||||
}
|
85
esp32c3/script/led_helper.lua
Normal file
85
esp32c3/script/led_helper.lua
Normal file
@ -0,0 +1,85 @@
|
||||
local led_helper = {}
|
||||
|
||||
local sys = require("sys")
|
||||
local config = require("config")
|
||||
|
||||
local status_led = gpio.setup(
|
||||
config.LED.LED_A,
|
||||
0,
|
||||
gpio.PULLUP)
|
||||
|
||||
local working_led = gpio.setup(
|
||||
config.LED.LED_B,
|
||||
0,
|
||||
gpio.PULLUP
|
||||
)
|
||||
|
||||
local function stop_and_clear_timer(timer)
|
||||
sys.timerStop(timer)
|
||||
timer = nil
|
||||
end
|
||||
|
||||
local is_status_led_on = true
|
||||
local status_led_blink_timer = nil
|
||||
function led_helper.blink_status_led(duration)
|
||||
if status_led_blink_timer then
|
||||
stop_and_clear_timer(status_led_blink_timer)
|
||||
end
|
||||
|
||||
status_led_blink_timer = sys.timerLoopStart(
|
||||
function ()
|
||||
status_led(is_status_led_on and 1 or 0)
|
||||
is_status_led_on = not is_status_led_on
|
||||
end,
|
||||
duration)
|
||||
end
|
||||
|
||||
local is_working_led_on = true
|
||||
local working_led_blink_timer = nil
|
||||
function led_helper.blink_working_led(duration)
|
||||
if working_led_blink_timer then
|
||||
stop_and_clear_timer(working_led_blink_timer)
|
||||
end
|
||||
|
||||
working_led_blink_timer = sys.timerLoopStart(
|
||||
function ()
|
||||
working_led(is_working_led_on and 1 or 0)
|
||||
is_working_led_on = not is_working_led_on
|
||||
end,
|
||||
duration
|
||||
)
|
||||
end
|
||||
|
||||
function led_helper.light_status_led()
|
||||
if status_led_blink_timer then
|
||||
stop_and_clear_timer(status_led_blink_timer)
|
||||
end
|
||||
|
||||
status_led(1)
|
||||
end
|
||||
|
||||
function led_helper.shut_status_led()
|
||||
if status_led_blink_timer then
|
||||
stop_and_clear_timer(status_led_blink_timer)
|
||||
end
|
||||
|
||||
status_led(0)
|
||||
end
|
||||
|
||||
function led_helper.light_working_led()
|
||||
if working_led_blink_timer then
|
||||
stop_and_clear_timer(working_led_blink_timer)
|
||||
end
|
||||
|
||||
working_led(1)
|
||||
end
|
||||
|
||||
function led_helper.shut_working_led()
|
||||
if working_led_blink_timer then
|
||||
stop_and_clear_timer(working_led_blink_timer)
|
||||
end
|
||||
|
||||
working_led(0)
|
||||
end
|
||||
|
||||
return led_helper
|
98
esp32c3/script/main copy.lua
Normal file
98
esp32c3/script/main copy.lua
Normal file
@ -0,0 +1,98 @@
|
||||
PROJECT = "sms_forwarder_wifi"
|
||||
VERSION = "1.0.0"
|
||||
|
||||
local sys = require("sys")
|
||||
local config = require("config")
|
||||
local constants = require("constants")
|
||||
local air780 = require("air780_helper")
|
||||
local led_helper = require("led_helper")
|
||||
local utils = require("utils")
|
||||
|
||||
require("sysplus")
|
||||
require("notification_helper")
|
||||
|
||||
if wdt then
|
||||
wdt.init(9000)
|
||||
sys.timerLoopStart(wdt.feed, 3000)
|
||||
end
|
||||
|
||||
log.setLevel(config.log_level)
|
||||
log.style(1)
|
||||
|
||||
log.info("bsp", rtos.bsp())
|
||||
log.info("mem_sys", rtos.meminfo("sys"))
|
||||
log.info("mem_lua", rtos.meminfo("lua"))
|
||||
|
||||
-- 每秒完整GC一次,防止内存不足问题
|
||||
sys.timerLoopStart(function()
|
||||
collectgarbage("collect")
|
||||
end, 1000)
|
||||
|
||||
led_helper.blink_status_led(constants.led_blink_duration.initializing)
|
||||
|
||||
sys.taskInit(function()
|
||||
local logging_tag = "main - 初始化网络"
|
||||
log.info(logging_tag, "正在连接无线网络"..config.wifi.ssid)
|
||||
wlan.init()
|
||||
wlan.setMode(wlan.STATION)
|
||||
wlan.connect(config.wifi["ssid"], config.wifi.password)
|
||||
sys.waitUntil("IP_READY")
|
||||
local ip_address = wlan.getIP()
|
||||
log.info(logging_tag, "无线网络连接成功,IP地址:"..ip_address)
|
||||
|
||||
for index, value in ipairs(config.dns_servers) do
|
||||
log.info(logging_tag, "配置第"..index.."个DNS服务器为"..value)
|
||||
socket.setDNS(nil, index, value)
|
||||
end
|
||||
|
||||
log.info(logging_tag, "等待时间同步")
|
||||
sys.waitUntil("NTP_UPDATE")
|
||||
log.info(logging_tag, "时间同步完成")
|
||||
end)
|
||||
|
||||
sys.taskInit(function ()
|
||||
local logging_tag = "main - 初始化Air780"
|
||||
local at_command_result
|
||||
|
||||
|
||||
if config.disable_netled then
|
||||
log.info(logging_tag, "正在关闭NET灯闪烁")
|
||||
air780.send_at_command("AT+CNETLIGHT=0")
|
||||
end
|
||||
|
||||
log.info(logging_tag, "初始化完成,等待新短信...")
|
||||
|
||||
-- 测试短信推送,解除注释可开机时自动模拟推送一条,用于模块独立测试
|
||||
-- sys.publish(
|
||||
-- constants.air780_message_topic_new_notification_request,
|
||||
-- '10086',
|
||||
-- '测试短信内容')
|
||||
|
||||
led_helper.light_status_led()
|
||||
end)
|
||||
|
||||
-- 收到新消息派发推送
|
||||
sys.subscribe(constants.air780_message_topic_new_sms_received,
|
||||
function(data)
|
||||
led_helper.blink_working_led(constants.led_blink_duration.working)
|
||||
sms_content = table.concat(data, "\n")
|
||||
if sms_content then
|
||||
log.info("main", "收到短信:"..sms_content)
|
||||
sys.publish(
|
||||
constants.air780_message_topic_new_notification_request,
|
||||
sms_content)
|
||||
led_helper.shut_working_led()
|
||||
return
|
||||
|
||||
else
|
||||
log.info("main", "收到来自"..phone_number.."的短信,即将转发...")
|
||||
sys.publish(
|
||||
constants.air780_message_topic_new_notification_request,
|
||||
sms_content)
|
||||
led_helper.shut_working_led()
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
sys.run()
|
234
esp32c3/script/main.lua
Normal file
234
esp32c3/script/main.lua
Normal file
@ -0,0 +1,234 @@
|
||||
PROJECT = "sms_to_wifi"
|
||||
VERSION = "1.0.0"
|
||||
|
||||
local sys = require("sys")
|
||||
local config = require("config")
|
||||
local led_helper = require("led_helper")
|
||||
local utils = require("utils")
|
||||
local util_notify = require("util_notify")
|
||||
local air780_helper = require("air780_helper")
|
||||
require("sysplus")
|
||||
|
||||
|
||||
if wdt then
|
||||
wdt.init(9000)
|
||||
sys.timerLoopStart(wdt.feed, 3000)
|
||||
end
|
||||
|
||||
log.setLevel(config.LOG_LEVEL)
|
||||
log.style(1)
|
||||
|
||||
log.info("bsp", rtos.bsp())
|
||||
log.info("mem_sys", rtos.meminfo("sys"))
|
||||
log.info("mem_lua", rtos.meminfo("lua"))
|
||||
-- 协议头
|
||||
local http_header = {["Content-Type"] = "application/json"}
|
||||
-- 每秒完整GC一次,防止内存不足问题
|
||||
sys.timerLoopStart(function()
|
||||
collectgarbage("collect")
|
||||
end, 1000)
|
||||
|
||||
led_helper.blink_status_led(config.LED_BLINK_DURATION.initializing)
|
||||
-- 初始化fskv非易失存储
|
||||
-- utils.clear_fskv()
|
||||
|
||||
-- 初始化网络
|
||||
sys.taskInit(function()
|
||||
local logging_tag = "main - 初始化网络"
|
||||
fskv.init()
|
||||
if fskv.kv_get("hostname") then
|
||||
wlan.hostname(fskv.kv_get("hostname"))
|
||||
else
|
||||
local mac = wlan.getMac()
|
||||
wlan.hostname("weiguo_" .. mac)
|
||||
end
|
||||
wlan.init()
|
||||
if fskv.kv_get("wlan_ssid") then
|
||||
wlan.connect(fskv.kv_get("wlan_ssid"), fskv.kv_get("wlan_passwd"))
|
||||
return
|
||||
end
|
||||
|
||||
log.info(logging_tag, "未配置wifi信息,开始配网!")
|
||||
wlan.smartconfig(wlan.AIRKISS)
|
||||
log.info(logging_tag, "开始微信配网")
|
||||
local ret, ssid, passwd = sys.waitUntil("SC_RESULT", 120*1000) -- 等2分钟
|
||||
if ret == true then
|
||||
fskv.kv_set("wlan_ssid", ssid)
|
||||
fskv.kv_set("wlan_passwd", passwd)
|
||||
log.info(logging_tag, "获取到wifi信息正在重启",ssid, passwd)
|
||||
sys.wait(1000)
|
||||
-- 官方推荐重启
|
||||
-- rtos.reboot()
|
||||
else
|
||||
-- smartconfig配置失败,开始AP模式网页配网。
|
||||
log.info(logging_tag, "网页配网","请连接ssid:weiguo_开头的wifi,打开:http://192.168.4.1进行配网")
|
||||
wlan.smartconfig(wlan.STOP)
|
||||
-- 设置为AP模式, 广播ssid, 接收wifi客户端的链接
|
||||
sys.wait(1000)
|
||||
wlan.setMode(wlan.AP)
|
||||
wlan.createAP("weiguo_" .. mac, "", "192.168.4.1", "255.255.255.0", 6)
|
||||
-- 监听80端口
|
||||
httpsrv.start(80, function(client, method, uri, headers, body)
|
||||
log.info("httpsrv", method, uri, json.encode(headers), body)
|
||||
if uri == "/" then
|
||||
return 200, http_header, '{"code":"1","msg":"等待配网"}'
|
||||
end
|
||||
if uri == "/config_wifi" then
|
||||
local wan_config = json.decode(body)
|
||||
if wan_config.ssid and wan_config.password then
|
||||
fskv.kv_set("wlan_ssid", wan_config.ssid)
|
||||
fskv.kv_set("wlan_passwd", wan_config.password)
|
||||
log.info(logging_tag, "配置成功,正在重启")
|
||||
wlan.connect(wan_config.ssid, wan_config.password)
|
||||
return 200, http_header, '{"code":"0","msg":"配置成功"}'
|
||||
-- 官方推荐重启
|
||||
-- rtos.reboot()
|
||||
else
|
||||
return 200, http_header, '{"code":"1","msg":"配置失败"}'
|
||||
end
|
||||
end
|
||||
return 404, {}, "Not Found" .. uri
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- 初始化设备CS针脚
|
||||
local function init_cs()
|
||||
for index, value in ipairs(config.CS_GPIO) do
|
||||
log.info("设备选择GPIO初始化", "配置第"..index.."个设备,GPIO:"..value,air780_helper.cs_index)
|
||||
gpio.setup(value, 0, gpio.PULLDOWN)
|
||||
end
|
||||
end
|
||||
-- 轮巡主函数
|
||||
local function loop_cs()
|
||||
if air780_helper.reading then
|
||||
return
|
||||
end
|
||||
if air780_helper.cs_index > #config.CS_GPIO then
|
||||
air780_helper.cs_index = 1
|
||||
end
|
||||
-- 统一拉低
|
||||
for index, value in ipairs(config.CS_GPIO) do
|
||||
gpio.setup(value, 0, gpio.PULLDOWN)
|
||||
end
|
||||
log.info("轮巡设备", air780_helper.cs_index," GPIO",config.CS_GPIO[air780_helper.cs_index])
|
||||
gpio.set(config.CS_GPIO[air780_helper.cs_index], gpio.HIGH)
|
||||
air780_helper.cs_index = air780_helper.cs_index + 1
|
||||
end
|
||||
|
||||
sys.taskInit(
|
||||
function()
|
||||
-- 联网完成 初始化
|
||||
sys.subscribe("IP_READY", function(ip)
|
||||
log.info("联网完成", "ip ready", ip)
|
||||
for index, value in ipairs(config.DNS_SERVERS) do
|
||||
log.info("联网完成", "配置第"..index.."个DNS服务器为"..value)
|
||||
socket.setDNS(nil, index, value)
|
||||
end
|
||||
led_helper.shut_status_led()
|
||||
led_helper.blink_working_led(config.LED_BLINK_DURATION.initializing)
|
||||
-- 设置设备CS针脚
|
||||
init_cs()
|
||||
-- 开启定时轮询
|
||||
sys.timerLoopStart(loop_cs, config.POLL_INTERVAL)
|
||||
end)
|
||||
log.info("bsp", rtos.bsp())
|
||||
log.info("mac", wlan.getMac())
|
||||
log.info("hostname", "weiguo_" .. wlan.getMac())
|
||||
-- 电源键短按发送测试通知
|
||||
sys.subscribe(
|
||||
"POWERKEY_SHORT_PRESS",
|
||||
function()
|
||||
log.info("main", "POWERKEY_SHORT_PRESS")
|
||||
util_notify.add(
|
||||
{
|
||||
from = "15264925507",
|
||||
sms = "本地测试短信通知并没有实际收到短信",
|
||||
from_time = "2024-03-14 00:00:00",
|
||||
sms_type = "正常",
|
||||
type = "sms"
|
||||
}
|
||||
)
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
-- 配置
|
||||
sys.taskInit(
|
||||
function()
|
||||
-- 监听80端口
|
||||
httpsrv.start(80, function(client, method, uri, headers, body)
|
||||
log.info("httpsrv", method, uri, json.encode(headers),"b", body)
|
||||
if uri == "/" then
|
||||
local numbers = fskv.kv_get("numbers")
|
||||
local ssid = fskv.kv_get("wlan_ssid")
|
||||
local passwd = fskv.kv_get("wlan_passwd")
|
||||
local config = {
|
||||
code = 0,
|
||||
msg = "完成",
|
||||
numbers = fskv.kv_get("numbers"),
|
||||
ssid = fskv.kv_get("wlan_ssid"),
|
||||
passwd = fskv.kv_get("wlan_passwd"),
|
||||
hostname = fskv.kv_get("hostname"),
|
||||
disable_boot = fskv.kv_get("disable_boot"),
|
||||
notify_type = config.NOTIFY_TYPE,
|
||||
notify_channel = {
|
||||
dingtalk = fskv.kv_get("dingtalk"),
|
||||
wecom = fskv.kv_get("wecom")
|
||||
}
|
||||
}
|
||||
return 200, http_header, json.encode(config)
|
||||
end
|
||||
if uri == "/config" then
|
||||
local web_config = json.decode(body)
|
||||
log.info("httpsrv", "配置数据", json.encode(web_config))
|
||||
if web_config.numbers ~= nil then
|
||||
fskv.kv_set("numbers", web_config.numbers)
|
||||
end
|
||||
if web_config.hostname ~= nil then
|
||||
fskv.kv_set("hostname", web_config.hostname)
|
||||
end
|
||||
if web_config.ssid ~= nil then
|
||||
fskv.kv_set("wlan_ssid", web_config.ssid)
|
||||
end
|
||||
if web_config.passwd ~= nil then
|
||||
fskv.kv_set("wlan_passwd", web_config.passwd)
|
||||
end
|
||||
if web_config.disable_boot == 1 or web_config.disable_boot == 0 then
|
||||
fskv.kv_set("disable_boot", web_config.disable_boot)
|
||||
end
|
||||
if web_config.ssid ~= nil or web_config.passwd ~= nil then
|
||||
log.info(logging_tag, "配置成功,正在联网")
|
||||
wlan.connect(wan_config.ssid, wan_config.password)
|
||||
-- 官方推荐重启
|
||||
-- rtos.reboot()
|
||||
end
|
||||
local notify_channel = {
|
||||
dingtalk = fskv.kv_get("dingtalk"),
|
||||
wecom = fskv.kv_get("wecom")
|
||||
}
|
||||
if web_config.notify_channel.dingtalk ~= nil then
|
||||
fskv.kv_set("dingtalk", web_config.notify_channel.dingtalk)
|
||||
end
|
||||
if web_config.notify_channel.wecom ~= nil then
|
||||
fskv.kv_set("wecom", web_config.notify_channel.wecom)
|
||||
end
|
||||
|
||||
|
||||
web_config.code = 0
|
||||
web_config.msg = "配置成功"
|
||||
if web_config.ssid ~= nil or web_config.passwd ~= nil then
|
||||
web_config.msg = "配置成功,设备即将重启!"
|
||||
return 200, http_header, json.encode(web_config)
|
||||
else
|
||||
return 200, http_header, json.encode(web_config)
|
||||
end
|
||||
end
|
||||
return 404, {}, "Not Found" .. uri
|
||||
end)
|
||||
end
|
||||
)
|
||||
|
||||
-- 启动
|
||||
sys.run()
|
212
esp32c3/script/util_notify.lua
Normal file
212
esp32c3/script/util_notify.lua
Normal file
@ -0,0 +1,212 @@
|
||||
local config = require("config")
|
||||
local utils = require("utils")
|
||||
local util_notify = {}
|
||||
local sys = require("sys")
|
||||
-- 消息队列
|
||||
local msg_queue = {}
|
||||
|
||||
local function urlencodeTab(params)
|
||||
local msg = {}
|
||||
for k, v in pairs(params) do
|
||||
table.insert(msg, string.urlEncode(k) .. "=" .. string.urlEncode(v))
|
||||
table.insert(msg, "&")
|
||||
end
|
||||
table.remove(msg)
|
||||
return table.concat(msg)
|
||||
end
|
||||
|
||||
local notify = {
|
||||
-- 发送到 dingtalk
|
||||
["dingtalk"] = function(msg)
|
||||
local dingtalk_webhook = fskv.kv_get("dingtalk")
|
||||
if utils.is_empty(dingtalk_webhook) then
|
||||
log.error("util_notify", "未配置钉钉机器人webhook地址")
|
||||
return
|
||||
end
|
||||
local title = ""
|
||||
if utils.is_empty(msg.from) == false then
|
||||
title = "来自" .. msg.from .. "的短信"
|
||||
else
|
||||
title = "短信设备通知"
|
||||
end
|
||||
local text = "##### " .. msg.sms .. "\n"
|
||||
if utils.is_empty(msg.from) == false then
|
||||
text = text .. "- 发送号码:".. msg.from .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.to) == false then
|
||||
text = text .. "- 设备号码:".. msg.to .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.hostname) == false then
|
||||
text = text .. "- 设备名称:".. msg.hostname .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.index) == false then
|
||||
text = text .. "- 子设备ID:".. msg.index .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.from_time) == false then
|
||||
text = text .. "- 接收时间:".. msg.from_time .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.oper) == false then
|
||||
text = text .. "- 运营商:".. msg.oper .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.rsrp) == false then
|
||||
text = text .. "- 信号强度:".. msg.rsrp .."\n"
|
||||
end
|
||||
local header = {
|
||||
["Content-Type"] = "application/json; charset=utf-8"
|
||||
}
|
||||
local body = {
|
||||
msgtype = "markdown",
|
||||
markdown = {
|
||||
title = title,
|
||||
text = text
|
||||
}
|
||||
}
|
||||
local json_data = json.encode(body)
|
||||
-- LuatOS Bug, json.encode 会将 \n 转换为 \b
|
||||
json_data = string.gsub(json_data, "\\b", "\\n")
|
||||
|
||||
log.info("util_notify", "POST", dingtalk_webhook)
|
||||
return utils.fetch(nil, "POST", dingtalk_webhook, header, json_data)
|
||||
end,
|
||||
|
||||
-- 发送到 wecom
|
||||
["wecom"] = function(msg)
|
||||
local wecom_webhook = fskv.kv_get("wecom")
|
||||
if utils.is_empty(wecom_webhook) then
|
||||
log.error("util_notify", "未配置企业微信机器人地址")
|
||||
return
|
||||
end
|
||||
|
||||
local header = {
|
||||
["Content-Type"] = "application/json; charset=utf-8"
|
||||
}
|
||||
local text = msg.sms .. "\n"
|
||||
if utils.is_empty(msg.from) == false then
|
||||
text = text .. "发送号码:".. msg.from .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.to) == false then
|
||||
text = text .. "设备号码:".. msg.to .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.hostname) == false then
|
||||
text = text .. "设备名称:".. msg.hostname .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.index) == false then
|
||||
text = text .. "设备ID:".. msg.index .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.from_time) == false then
|
||||
text = text .. "接收时间:".. msg.from_time .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.oper) == false then
|
||||
text = text .. "运营商:".. msg.oper .."\n"
|
||||
end
|
||||
if utils.is_empty(msg.rsrp) == false then
|
||||
text = text .. "信号强度:".. msg.rsrp .."\n"
|
||||
end
|
||||
local body = {
|
||||
msgtype = "text",
|
||||
text = {
|
||||
content = text
|
||||
}
|
||||
}
|
||||
local json_data = json.encode(body)
|
||||
-- LuatOS Bug, json.encode 会将 \n 转换为 \b
|
||||
json_data = string.gsub(json_data, "\\b", "\\n")
|
||||
|
||||
log.info("util_notify", "POST", wecom_webhook)
|
||||
return utils.fetch(nil, "POST", wecom_webhook, header, json_data)
|
||||
end
|
||||
}
|
||||
|
||||
--- 发送通知
|
||||
-- @param msg 消息内容
|
||||
-- @param channel 通知渠道
|
||||
-- @return true: 无需重发, false: 需要重发
|
||||
function util_notify.send(msg, channel)
|
||||
log.info("util_notify.send", "发送通知", channel)
|
||||
|
||||
-- 判断消息内容 msg
|
||||
if type(msg) ~= "table" then
|
||||
log.error("util_notify.send", "发送通知失败", "参数类型错误", type(msg))
|
||||
return true
|
||||
end
|
||||
if msg.sms == "" then
|
||||
log.error("util_notify.send", "发送通知失败", "消息内容为空")
|
||||
return true
|
||||
end
|
||||
|
||||
-- 判断通知渠道 channel
|
||||
if channel and notify[channel] == nil then
|
||||
log.error("util_notify.send", "发送通知失败", "未知通知渠道", channel)
|
||||
return true
|
||||
end
|
||||
|
||||
-- 发送通知
|
||||
local code, headers, body = notify[channel](msg)
|
||||
if code == nil then
|
||||
log.info("util_notify.send", "发送通知失败, 无需重发", "code:", code, "body:", body)
|
||||
return true
|
||||
end
|
||||
if code == -6 then
|
||||
-- 发生在 url 过长时, 重发也不会成功
|
||||
log.info("util_notify.send", "发送通知失败, 无需重发", "code:", code, "body:", body)
|
||||
return true
|
||||
end
|
||||
if code >= 200 and code < 500 then
|
||||
log.info("util_notify.send", "发送通知成功", "code:", code, "body:", body)
|
||||
return true
|
||||
end
|
||||
log.error("util_notify.send", "发送通知失败, 等待重发", "code:", code, "body:", body)
|
||||
return false
|
||||
end
|
||||
|
||||
--- 添加到消息队列
|
||||
-- @param msg 消息内容
|
||||
-- @param channels 通知渠道
|
||||
function util_notify.add(msg, channels)
|
||||
log.info("util_notify.add", "添加到消息队列")
|
||||
if type(msg) ~= "table" then
|
||||
log.info("util_notify.add", "添加消息失败", "参数错误")
|
||||
end
|
||||
channels = channels or config.NOTIFY_TYPE
|
||||
if type(channels) ~= "table" then
|
||||
channels = {channels}
|
||||
end
|
||||
for _, channel in ipairs(channels) do
|
||||
table.insert(msg_queue, {channel = channel, msg = msg, retry = 0})
|
||||
end
|
||||
sys.publish("ADD_NEW_MSG")
|
||||
log.debug("util_notify.add", "添加到消息队列, 当前队列长度:", #msg_queue)
|
||||
end
|
||||
|
||||
-- 轮询消息队列
|
||||
-- 发送成功则从消息队列中删除
|
||||
-- 发送失败则等待下次轮询
|
||||
local function poll()
|
||||
local item, result
|
||||
while true do
|
||||
-- 消息队列非空, 且网络已注册
|
||||
if next(msg_queue) ~= nil then
|
||||
log.debug("util_notify.poll", "轮询消息队列中, 当前队列长度:", #msg_queue)
|
||||
item = msg_queue[1]
|
||||
table.remove(msg_queue, 1)
|
||||
if item.retry > (config.NOTIFY_RETRY_MAX or 100) then
|
||||
log.error("util_notify.poll", "超过最大重发次数", "消息内容:", json.encode(item.msg))
|
||||
else
|
||||
result = util_notify.send(item.msg, item.channel)
|
||||
item.retry = item.retry + 1
|
||||
if not result then
|
||||
-- 发送失败, 移到队尾
|
||||
table.insert(msg_queue, item)
|
||||
sys.wait(5000)
|
||||
end
|
||||
end
|
||||
sys.wait(50)
|
||||
else
|
||||
sys.waitUntil("ADD_NEW_MSG", 1000 * 10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sys.taskInit(poll)
|
||||
|
||||
return util_notify
|
65
esp32c3/script/utils.lua
Normal file
65
esp32c3/script/utils.lua
Normal file
@ -0,0 +1,65 @@
|
||||
local utils = {}
|
||||
local sys = require("sys")
|
||||
function utils.bool_to_number(value)
|
||||
return value and 1 or 0
|
||||
end
|
||||
|
||||
function utils.is_empty(str)
|
||||
return str == nil or str == ""
|
||||
end
|
||||
|
||||
function utils.clear_table(table)
|
||||
for i = 0, #table do
|
||||
table[i] = nil
|
||||
end
|
||||
end
|
||||
function utils.table_len(t)
|
||||
local leng=0
|
||||
if type(t) ~= "table" then
|
||||
return leng
|
||||
end
|
||||
for k, v in pairs(t) do
|
||||
leng=leng+1
|
||||
end
|
||||
return leng;
|
||||
end
|
||||
function utils.clear_fskv()
|
||||
fskv.init()
|
||||
fskv.clear()
|
||||
end
|
||||
-- 用于生成 http 请求的 id
|
||||
local http_count = 0
|
||||
|
||||
--- 对 LuatOS-Air http.request 的封装
|
||||
-- @param timeout (number) 超时时间
|
||||
-- @param method (string) 请求方法
|
||||
-- @param url (string) 请求地址
|
||||
-- @param headers (table) 请求头
|
||||
-- @param body (string) 请求体
|
||||
-- @return (number, table, string) 状态码, 响应头, 响应体
|
||||
function utils.fetch(timeout, method, url, headers, body)
|
||||
|
||||
local code,headers,body = http.request(method, url, headers,body).wait()
|
||||
return code, headers, body
|
||||
-- timeout = timeout or 1000 * 30
|
||||
|
||||
-- http_count = http_count + 1
|
||||
-- local id = "http_c" .. http_count .. "_r" .. math.random(1000, 9999)
|
||||
|
||||
-- local function callback(res_result, res_prompt, res_headers, res_body)
|
||||
-- sys.publish(id, {res_result, res_prompt, res_headers, res_body})
|
||||
-- end
|
||||
|
||||
-- log.info("utils.fetch", "开始请求", "id:", id)
|
||||
-- http.request(method, url, nil, headers, body, timeout, callback)
|
||||
-- local result, data = sys.waitUntil(id, 1000 * 60)
|
||||
-- log.info("utils.fetch", "请求结束", "id:", id)
|
||||
|
||||
-- if result == false then
|
||||
-- log.warn("utils.fetch", "请求超时", "id:", id)
|
||||
-- return 501, {}, "utils.fetch 请求超时"
|
||||
-- end
|
||||
|
||||
-- return tonumber(data[2]) or -99, data[3] or {}, data[4] or ""
|
||||
end
|
||||
return utils
|
Loading…
Reference in New Issue
Block a user