--[[
@module  network_watchdog
@summary 网络环境检测看门狗功能模块
@version 1.0
@date    2025.07.23
@author  朱天华
@usage
本文件为网络环境检测看门狗功能模块，监控网络环境是否工作正常（设备和服务器双向通信正常，或者至少单向通信正常），核心业务逻辑为：
1、启动一个网络环境检测看门狗task，等待其他mqtt网络应用功能模块来喂狗，如果喂狗超时，则控制软件重启；
2、如何确定“喂狗超时时间”，一般来说，有以下几个原则；
   (1) 先确定一个最小基准值T1，2分钟或者5分钟或者10分钟，这个取值取决于具体项目需求，但是不能太短，因为开机后，在网络环境不太好的地方，网络初始化可能需要比较长的时间，一般推荐这个值不能小于2分钟；
   (2) 再确定一个和产品业务逻辑有关的一个值T2，这个值和产品的应用业务逻辑息息相关，假设你的产品业务中：
       <1> 服务器会定时下发数据给设备，例如设备连接上业务服务器之后，每隔3分钟，设备都会给服务器发送一次心跳，然后服务器都会立即回复一个心跳应答包；
           这种情况下，可以取3分钟的大于等于1的倍数(例如1倍，1.5倍，2倍等等)+一段时间(例如10秒钟，如果前面是1倍，则此处必须加一段时间，给网络数据传输过程留够充足的时间)；
       <2> mqtt本身有keep alive的心跳机制，例如设备连接上业务服务器之后，默认每隔2分钟，设备都会给服务器发送一次心跳，服务器也会回复一个心跳应答数据；
           这种情况下，可以取2分钟的大于等于1的倍数(例如1倍，1.5倍，2倍等等)+一段时间(例如10秒钟，如果前面是1倍，则此处必须加一段时间，给网络数据传输过程留够充足的时间)；
    (3) 取T1和T2的最大值，就是“喂狗超时时间”
3、其他mqtt网络业务功能模块的喂狗时机，和上面2.2的描述相对应，一般来说，可以在以下几种时间点执行喂狗动作：
   (1) 设备收到服务器下发的数据时
   (2) 设备收到服务器回复的mqtt心跳应答数据时
4、最重要的一点是：以上所说的原则，仅仅是建议，要根据自己的实际项目业务逻辑以及自己的需求最终确定看门狗方案

5、具体到本demo
   (1) 产品业务逻辑为：
       <1> 创建了一个mqtt连接，设备每隔5秒钟发送一次数据到服务器，服务器何时下发应用数据给设备不确定；
       <2> 创建了一个mqtt ssl、不需要证书校验的连接，设备每隔5秒钟发送一次数据到服务器，服务器何时下发应用数据给设备不确定；
       <3> 创建了一个mqtt ssl、client单向校验server证书的连接，设备每隔5秒钟发送一次数据到服务器，服务器何时下发应用数据给设备不确定；
       <4> 每隔3分钟，这三路mqtt连接都会发送一次mqtt心跳给server，server收到心跳后回复心跳应答给client；
   (2) 确定喂狗超时时间：
       <1> 本demo支持单WIFI、单以太网、单4G网络连接外网，网络环境准备就绪预留2分钟的时间已经足够，所以最小基准值T1取值2分钟；
       <2> 本demo中存在3路mqtt连接，但是这3路mqtt连接都没有定时或者至少一段时间，服务器下发应用数据给设备，所以无法基于服务器下发应用数据的业务逻辑来确定T2的值；
       <3> 本demo中存在3路mqtt连接，每1路mqtt连接，设备都是3分钟发送一次mqtt心跳数据给服务器，服务器收到后会立即回复一个mqtt心跳应答数据给设备；
           所以可以通过3分钟的大于等于1的倍数(例如1倍，1.5倍，2倍等等)+一段时间(例如10秒钟，如果前面是1倍，则此处必须加一段时间，给网络数据传输过程留够充足的时间)来确定T2的值；
           在这个demo中，我能接受的网络连续异常时长是5分钟，所以，T2取值5分钟；
       <4> 取T1 2分钟和T2 5分钟的最大值，最终的喂狗超时时间就是5分钟；
   (3) 确定喂狗时机：
       <1> 3路mqtt连接中，任何1路收到服务器的下发的应用数据时；
       <2> 3路mqtt连接中，任何1路收到服务器的回复的心跳应答数据时；
6、本demo设计的网络环境检测看门狗功能模块，可以检测以下两种种的任意一种网络环境异常：
   (1) 网络环境连续超过5分钟没有准备就绪
   (2) mqtt、mqtt ssl、mqtt ssl单向校验证书3路连接中，连续5分钟没有收到服务器下发的应用数据或者服务器回复的心跳应答数据； 


本文件没有对外接口，直接在main.lua中require "network_watchdog"就可以加载运行；
外部功能模块喂狗时，直接调用sys.publish("FEED_NETWORK_WATCHDOG")
]]

-- 网络环境检测看门狗task处理函数
local function network_watchdog_task_func()
    while true do
        --如果等待180秒没有等到"FEED_NETWORK_WATCHDOG"消息，则看门狗超时
        if not sys.waitUntil("FEED_NETWORK_WATCHDOG", 300000) then
            log.error("network_watchdog_task_func timeout")
            -- 等待3秒钟，然后软件重启
            sys.wait(3000)
            rtos.reboot()
        end
    end
end

--创建并且启动一个task
--运行这个task的处理函数network_watchdog_task_func
sys.taskInit(network_watchdog_task_func)
