Bläddra i källkod

g33 first push

nana_sen 2 år sedan
incheckning
b7d6354d0c
13 ändrade filer med 3138 tillägg och 0 borttagningar
  1. 49 0
      config.lua
  2. 17 0
      devTool.lua
  3. 91 0
      g33mqtt.lua
  4. 119 0
      gpsTask.lua
  5. 12 0
      ledTask.lua
  6. 145 0
      logModuel.lua
  7. 26 0
      luatide_project.json
  8. 46 0
      main.lua
  9. 1609 0
      modbusTT.lua
  10. 248 0
      mqtt_recieve.lua
  11. 28 0
      otaTask.lua
  12. 104 0
      powerManage.lua
  13. 644 0
      sdModuel.lua

+ 49 - 0
config.lua

@@ -0,0 +1,49 @@
+module(...)
+-- mqtt配置
+mqttIp = "develop.rltest.cn"
+mqttPort = "1883"
+mqttUser = "rl517"
+mqttPassword = "rlian2022"
+--ota升级参数配置
+otaUrl = "47.114.185.186:11113/api/site/firmware_upgrade"
+--ota升级检查周期
+otaCheckInterval = 1200
+-- 本地数据最新版本号
+localCntVersion = "1662371022371"
+-- 心跳间隔/s
+heartbeatInterval = 600
+
+
+-- GPS相关
+gpsEnable = 1
+gpsLng = "0"
+lngType = "X"
+--GPS主动定位纬度
+gpsLat = "0"
+latType = "X"
+--gps主动定位时间
+gpsTime = 1660789298
+
+
+-- 泵状态相关 
+pumbStatus = 0 -- 设备状态  0、无状态      1、待机       2、设备运行       3、故障    4、远程锁定
+-- 维保状态
+hydOil = 0  --液压油寿命当前值
+scaleValve = 0  --比例阀寿命当前值
+elecValve = 0  --电磁阀寿命当前值
+
+hydOilThr = 90 --液压油告警阈值
+scaleValveThr = 90--比例阀告警阈值
+elecValveThr = 90--电磁阀告警阈值
+ 
+lastWorkField = "444441" --上次作业风场编号
+fieldDisplayRadius = 20
+
+--错误日志上报地址
+errorLogReportUrl = "udp://47.114.185.186:11114"
+errorLogReportInterval = 600
+--重启次数
+bootNum = 0
+
+
+

+ 17 - 0
devTool.lua

@@ -0,0 +1,17 @@
+module(..., package.seeall)
+
+PI = 3.14159265359
+ERadius = 6371.393
+function getDistance( lat1, lng1, lat2, lng2 )
+    -- body
+    local radLat1 = lat1 * (PI / 180)
+    local radLat2 = lat2 * (PI / 180)
+
+    local a = radLat1 - radLat2
+    local b = (lng1 * (PI / 180)) - (lng2 * (PI / 180))
+    
+    local s = 2 * math.asin(math.sqrt(math.pow(math.sin(a/2),2) + math.cos(radLat1)*math.cos(radLat2)*math.pow(math.sin(b/2),2)))
+    local s = s * ERadius
+    local s = math.floor(s * 10000+0.5) / 10000
+    return s
+end

+ 91 - 0
g33mqtt.lua

@@ -0,0 +1,91 @@
+module(..., package.seeall)
+require "mqtt"
+require "sim"
+require "net"
+require "misc"
+require "pins"
+require "nvm"
+require"mqtt_recieve"
+-- require"mqtt_send"
+
+
+
+
+local host, port = nvm.get("mqttIp") or "develop.rltest.cn", nvm.get("mqttPort") or "1883"
+local username = nvm.get("mqttUser") or "rl517"
+local password = nvm.get("mqttPassword") or "rlian2022"
+
+
+--mqttc 连接状态
+local isConnected = false
+local isWaitReconnect = false
+--ota 升级检测是否结束
+local isOtaCheckEnd = false
+--等待ota升级检测结束
+-- sys.subscribe("ota_update_check_end", function(data)
+--     isOtaCheckEnd = true
+-- end)
+
+
+
+
+--启动MQTT客户端任务
+sys.taskInit(
+    function()
+        local retryConnectCnt = 0
+        while true do
+            if not socket.isReady() then
+                retryConnectCnt = 0
+                --等待网络环境准备就绪,超时时间是5分钟
+                log.info("socket 1 is not ready")
+                sys.wait(1000)
+                sys.waitUntil("IP_READY_IND",300000)
+            end
+            
+            if socket.isReady() then
+                local imei = misc.getImei()
+                --创建一个MQTT客户端
+                local mqttClient = mqtt.client(imei,300,username,password)
+                --阻塞执行MQTT CONNECT动作,直至成功
+                --如果使用ssl连接,打开mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"}),根据自己的需求配置
+                --mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"})
+                if mqttClient:connect(host,port,"tcp") then
+                    log.info("imei:", imei)
+                    retryConnectCnt = 0
+                    isConnected = true
+                    --订阅主题
+                    local topics = {
+                        ["SHEGCL/IntelligenTool/UpdateToolInfo/"..imei] = 0, 
+                        ["SHEGCL/TestR/"..imei]=0
+                    }
+                    if mqttClient:subscribe(topics) then
+                        --循环处理接收和发送的数据
+                        while true do
+                            -- if not mqtt_send.proc(mqttClient) then log.error("mqttTask.mqtt_send proc error") break end
+                            if not mqtt_recieve.proc(mqttClient) then log.error("mqttTask.mqtt_recieve.proc error") break end
+                            
+                            -- local a = mqtt_send.proc(mqttClient)
+                            -- log.info("send proc res",  a)
+                        end
+                    end
+                    isConnected = false
+                else
+                    retryConnectCnt = retryConnectCnt+1
+                end
+                --断开MQTT连接
+                mqttClient:disconnect()
+                if retryConnectCnt>=5 then link.shut() retryConnectCnt=0 end
+                sys.wait(5000)
+            else
+                --进入飞行模式,20秒之后,退出飞行模式
+                net.switchFly(true)
+                sys.wait(20000)
+                net.switchFly(false)
+            end
+        end
+    end
+)
+
+
+
+

+ 119 - 0
gpsTask.lua

@@ -0,0 +1,119 @@
+
+
+local gps = require"gpsZkw"
+
+local gpsEnable = nvm.get("gpsEnable") or 1
+local gpsTimerId
+
+local function setGpsInfo()
+    local tLocation = gps.getLocation()--获取度格式的经纬度信息
+    local speed = gps.getSpeed()
+    log.info("testGps.printGps",
+        gps.isOpen(),--获取GPS模块是否处于开启状态,gps.isFix()--获取GPS模块是否定位成功,
+        tLocation.lngType,tLocation.lng,tLocation.latType,tLocation.lat,--打印经纬度
+        gps.getAltitude(),--获取海拔
+        speed,--获取速度
+        gps.getCourse(),--获取方向角
+        gps.getViewedSateCnt(),--获取可见卫星的个数
+        gps.getUsedSateCnt())--获取定位使用的卫星个数
+
+        if gps.isFix() then
+            log.info("gpsTask.printGps","location success,close gps ... ")
+            gpsLocation = tLocation
+            --断电GPS
+            pins.setup(pio.P0_18, 1)
+            pins.setup(pio.P0_3, 0)
+            --保存定位数据到flash
+            if gpsEnable == 1 then
+                local gpsLng = nvm.get("gpsLng") or "0"
+                if gpsLng ~= gpsLocation.lng then
+                    if not nvm.set("gpsLng",gpsLocation.lng) then
+                        log.error("gpsTask.printGps","nvm.set  gpsLng fail! gpsLng:", gpsLocation.lng)
+                        return
+                    end
+                end
+                local lngType = nvm.get("lngType") or "0"
+                if lngType ~= gpsLocation.lngType then
+                    if not nvm.set("lngType",gpsLocation.lngType) then
+                        log.error("gpsTask.printGps","nvm.set  lngType fail! lngType:", gpsLocation.lngType)
+                        return
+                    end
+                end
+                local gpsLat = nvm.get("gpsLat") or "0"
+                if gpsLat ~= gpsLocation.lat then
+                    if not nvm.set("gpsLat",gpsLocation.lat) then
+                        log.error("gpsTask.printGps","nvm.set  gpsLat fail! gpsLat:", gpsLocation.lat)
+                        return
+                    end
+                end
+                local latType = nvm.get("latType") or "0"
+                if latType ~= gpsLocation.latType then
+                    if not nvm.set("latType",gpsLocation.latType) then
+                        log.error("gpsTask.printGps","nvm.set  latType fail! latType:", gpsLocation.latType)
+                        return
+                    end
+                end
+                local gpsTime = nvm.get("gpsTime") or 0
+                if gpsTime ~= os.time() then
+                    if not nvm.set("gpsTime",os.time()) then
+                        log.error("gpsTask.printGps","nvm.set  gpsTime fail! gpsTime:", os.time())
+                        return
+                    end
+                end
+                sys.publish("pub_gps_location_success_msg",tLocation)
+            end
+        end
+
+end
+
+
+function printGps()
+    -- body
+    local tLocation = gps.getLocation()--获取度格式的经纬度信息
+    local speed = gps.getSpeed()
+    log.info("testGps.printGps",
+        gps.isOpen(),--获取GPS模块是否处于开启状态,gps.isFix()--获取GPS模块是否定位成功,
+        tLocation.lngType,tLocation.lng,tLocation.latType,tLocation.lat,--打印经纬度
+        gps.getAltitude(),--获取海拔
+        speed,--获取速度
+        gps.getCourse(),--获取方向角
+        gps.getViewedSateCnt(),--获取可见卫星的个数
+        gps.getUsedSateCnt())--获取定位使用的卫星个数
+end 
+
+function gpsLocateCb(  )
+    -- body
+    sys.timerStop(gpsTimerId)
+    setGpsInfo()
+    pins.setup(pio.P0_3, 0) --GPS复位
+    pins.setup(pio.P0_18, 1) --关闭GPS供电
+
+end
+
+
+
+gps.setUart(3,9600,8,uart.PAR_NONE,uart.STOP_1)
+function openGpsSwitch( )
+    -- body
+
+    if gpsEnable == 1 then 
+        -- body
+        --中科微GPS
+        --打开GPS供电
+        pins.setup(pio.P0_18, 0)
+        --拉高GPS工作,拉低GPS复位
+        pins.setup(pio.P0_3, 1)
+
+
+        if not gps.isOpen() then
+            -- body
+            gpsTimerId = sys.timerLoopStart(printGps,4000)
+            gps.open(gps.TIMERORSUC,{tag="GPS_TAG",val=120,cb=gpsLocateCb})
+        end
+
+    end
+end
+
+openGpsSwitch()
+
+sys.timerLoopStart(openGpsSwitch,1800*1000)

+ 12 - 0
ledTask.lua

@@ -0,0 +1,12 @@
+require "led"
+require "pins"
+
+pmd.ldoset(2,pmd.LDO_VLCD)
+
+-- local blueLed = pins.setup(pio.P0_2, 0)
+-- local redLed = pins.setup(pio.P0_0, 0)
+
+netLed.setup(true, pio.P0_2)
+
+netLed.updateBlinkTime("SCK",1000,4000)
+netLed.updateBlinkTime("SIMERR",0,0xFFFF)

+ 145 - 0
logModuel.lua

@@ -0,0 +1,145 @@
+
+module(...,package.seeall)
+
+
+local logSize = 32 -- 单位kb
+local logDir = '/sdcard0/log' -- 日志目录
+local logCnt = 5 -- 保留日志文件个数
+
+function hex_tonumber(hex_str)
+    local num = tonumber(hex_str, 16)
+    return num
+end
+-- 数字进制转换
+---@param num number 十进制数字
+---@param hex number 转换的目标进制数(2-16)
+---@return string
+function Dec2Hex(num, hex)
+    if num == nil or type(num) ~= "number" then return num end
+    if hex == nil then return num end
+    local hexMap = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', "C", 'D', 'E', 'F'}
+    local v = {}
+    local s = math.floor(num / hex)
+
+    local y = num % hex
+    table.insert(v, 1, y)
+    while s >= hex do
+        y = s % hex
+        table.insert(v, 1, y)
+        s = math.floor(s / hex)
+    end
+    table.insert(v, 1, s)
+
+    local r = ""
+    for _, k in ipairs(v) do r = r .. hexMap[k + 1] end
+    return r
+end
+
+-- 打开sd卡日志目录,不存在则创建,返回最新文件名称
+function getLastFile(dirPath)
+    log.info('open dir', io.opendir(dirPath))
+    if io.opendir(dirPath) ~= 0 then
+        local file = {} -- 该目录所有文件名
+        for i = 1, 999 do
+            local fType, fName, fSize = io.readdir()
+            -- log.info("file or dir",fType, fName, fSize)
+            if fType == 32 then
+                log.info("sd card file", fName, fSize)
+                file[i] = hex_tonumber(fName)
+                -- local c = io.readFile(dirPath..'/'..fName)
+                -- log.info('文件内容',c)
+            elseif fType == nil then
+                -- 文件个数达到设置值,删除旧文件
+                log.info('文件个数', i - 1)
+                local min = nil -- 最旧的文件  即数字名称值最小的文件
+                for i, v in pairs(file) do
+                    if min == nil then min = v end
+                    if min > v then min = v end
+                end
+                log.info('min', min)
+                if min then
+                    if i - 1 > logCnt then
+                        log.debug('del file path',
+                                  dirPath .. '/' .. Dec2Hex(min, 16))
+                        local del =
+                            os.remove(dirPath .. '/' .. Dec2Hex(min, 16))
+                        log.info('del old file', del)
+                    end
+                end
+                break
+            end
+        end
+        local max = nil -- 最新的文件  即数字名称值最大的文件
+        for i, v in pairs(file) do
+            v = tonumber(v) --数组中是string类型   比较会有问题
+            if max == nil then max = v end
+            if max < v then max = v end
+        end
+        if max then
+            -- 判断该最新文件大小
+            local cnt = io.fileSize(dirPath .. '/' .. Dec2Hex(max, 16))
+            if cnt then
+                if cnt >= (logSize * 1024) then -- 文件大于设置的文件大小 新建新文件
+                    max = max + 1
+                end
+            end
+            io.closedir()
+            return Dec2Hex(max, 16)
+        else
+            io.closedir()
+            return nil
+        end
+    else
+        local cdir = rtos.make_dir(dirPath)
+        log.info('创建目录成功', cdir)
+    end
+end
+-- 写入日志数据
+function debug_log(msg)
+    local dirPath = logDir
+    local file = getLastFile(dirPath)
+    if file then
+        log.debug('last file name', file)
+        file = dirPath .. '/' .. file
+    else
+        file = dirPath .. '/' .. Dec2Hex(1, 16)
+    end
+    log.info('filepath', type(file), file)
+    local t = os.date("*t")
+    t = string.format("%04d-%02d-%02d %02d:%02d:%02d", t.year, t.month, t.day,
+                      t.hour, t.min, t.sec)
+    log.info('当前时间:', t)
+    local msg = t .. ' ' .. msg .. '\n'
+    local c = io.writeFile(file, msg, "a+b")
+    if c then
+        log.info('msg', msg)
+    else
+        log.error('error', '日志文件写入失败')
+    end
+end
+
+-- 读取日志
+--[[
+    函数名:readfile(filename)
+    功能:打开所输入文件名的文件,并输出储存在里面额内容
+    参数:完整路径文件名
+    返回值:无                     ]]
+  function readfile(filename) -- 打开指定文件并输出内容  filename = nil打开最新文件
+    if not filename or filename == '/sdcard0/log/0' then
+        filename = logDir .. '/' .. getLastFile(logDir)
+    end
+    local headval = '文件名' .. filename .. '\n' -- 文件头部
+    local fileval = nil -- 文件内容
+    local filehandle = io.open(filename, "r") -- 第一个参数是文件名,第二个是打开方式,'r'读模式,'w'写模式,对数据进行覆盖,'a'附加模式,'b'加在模式后面表示以二进制形式打开
+    if filehandle then -- 判断文件是否存在
+        fileval = filehandle:read("*all") -- 读出文件内容
+        if fileval then
+            filehandle:close() -- 关闭文件
+        else
+            fileval = "文件为空" -- 文件不存在
+        end
+    else
+        fileval = "文件不存在或文件输入格式不正确" -- 打开失败
+    end
+    return headval..fileval
+end

+ 26 - 0
luatide_project.json

@@ -0,0 +1,26 @@
+{
+	"version": "2.6",
+	"projectName": "G33_GATEWAY",
+	"projectType": "pure",
+	"moduleModel": "air72XUX/air82XUX",
+	"simulatorRun": "disable",
+	"corePath": "C:\\Users\\boringsoft\\AppData\\Roaming\\LuatIDE\\LuatideCore\\Air72XUX_CORE\\LuatOS-Air_V4010_RDA8910_BT_FLOAT.pac",
+	"libPath": "C:\\Users\\boringsoft\\AppData\\Roaming\\LuatIDE\\LuatideLib\\Air72XUX_LIB\\V2.4.3\\lib",
+	"modulePort": "",
+	"appFile": [
+		"config.lua",
+		"devTool.lua",
+		"g33mqtt.lua",
+		"gpsTask.lua",
+		"ledTask.lua",
+		"logModuel.lua",
+		"luatide_project.json",
+		"main.lua",
+		"modbusTT.lua",
+		"mqtt_recieve.lua",
+		"otaTask.lua",
+		"powerManage.lua",
+		"sdModuel.lua"
+	],
+	"ignore": []
+}

+ 46 - 0
main.lua

@@ -0,0 +1,46 @@
+PROJECT = "Rlian-GATEWAY-G33"
+VERSION = "1.0.11"
+PRODUCT_KEY = "ddd0422aef65441cbe1c6cccd84e2fa0"
+require 'log'
+LOG_LEVEL = log.LOGLEVEL_TRACE
+require 'sys'
+
+require "ntp"
+require "common"
+require "net"
+require "nvm"
+require "config"
+
+nvm.init("config.lua")
+--开机次数+1
+nvm.set("bootNum", nvm.get("bootNum") + 1)	
+
+require "netLed"
+
+ntp.timeSync()
+
+require "errDump"
+-- errDump.request("udp://ota.airm2m.com:9072")
+errDump.setNetworkLog(true)
+local errorLogReportUrl = nvm.get("errorLogReportUrl") or "udp://47.114.185.186:11114"
+local errorLogReportInterval = nvm.get("errorLogReportInterval") or 600
+errDump.request(errorLogReportUrl,errorLogReportInterval*1000)
+
+require "devTool"
+require "sdModuel"
+require "logModuel"
+require "gpsTask"
+require "ledTask"
+require "g33mqtt"
+require "modbusTT"
+require "otaTask"
+require "powerManage"
+
+-- 自动垃圾回收
+collectgarbage("setpause", 90)
+
+
+
+
+sys.init(0, 0)
+sys.run()

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1609 - 0
modbusTT.lua


+ 248 - 0
mqtt_recieve.lua

@@ -0,0 +1,248 @@
+module(...,package.seeall)
+
+local DIR_PATH = {
+    Users = "/sdcard0/common",
+    Wrench = "/sdcard0/common",
+    WorkingParts = "/sdcard0/common",
+    WorkingPosition = "/sdcard0/common",
+    WorkPlan = "/sdcard0/common",
+    File = "/sdcard0/log",
+    Wind = "/sdcard0/common"
+}
+
+local ALLOWCUSTOM_FILE = {
+    Fan = 1,
+    WorkingParts = 1,
+    WorkingPosition = 1
+}
+-- 根据操作写文件
+function operateFs(op, cntType, cntVersion, content )
+    -- body
+    local opRes, count, desc = "",fileRes
+
+    if op == "add" then
+        -- body
+        if DIR_PATH[cntType] then
+            -- body 
+            if ALLOWCUSTOM_FILE[cntType] then
+                -- body
+                delBaseInfo(cntType, 0, DIR_PATH[cntType])
+            end
+            opRes, desc =  saveBaseInfo(cntType, content, DIR_PATH[cntType] )
+        else
+            if ALLOWCUSTOM_FILE[cntType] then
+                -- body
+                delBaseInfo(cntType, 0, "/sdcard0/"..content.wnum)
+            end
+
+            if cntType == "WorkRecord" then
+                -- body
+                opRes, desc = saveBaseInfo(cntType, content, "/sdcard0/"..content.wnum .. "/" .. content.fnum)
+            else
+                opRes, desc = saveBaseInfo(cntType, content, "/sdcard0/"..content.wnum )
+            end
+        end
+
+    end
+    if op == "update" then
+        -- body
+        if DIR_PATH[cntType]  then
+            -- body 
+            opRes,count, desc =  updateBaseInfo(cntType, content, DIR_PATH[cntType] )
+
+            if not opRes or desc:sub(1, 29) == "this data not found where id=" then
+                -- body
+                opRes, desc =  saveBaseInfo(cntType, content, DIR_PATH[cntType] )
+            end
+
+        else
+            if cntType == "WorkRecord" then
+                -- body
+                opRes,count, desc = updateBaseInfo(cntType, content, "/sdcard0/"..content.wnum .. "/" .. content.fnum)
+            else
+                opRes,count, desc = updateBaseInfo(cntType, content, "/sdcard0/"..content.wnum )
+            end
+
+            if not opRes or desc:sub(1, 29) == "this data not found where id=" then
+                -- body
+                if cntType == "WorkRecord" then
+                    -- body
+                    opRes, desc = saveBaseInfo(cntType, content, "/sdcard0/"..content.wnum .. "/" .. content.fnum)
+                else
+                    opRes, desc = saveBaseInfo(cntType, content, "/sdcard0/"..content.wnum )
+                end
+            end
+        end
+
+    end
+    if op == "delete" then
+        -- body
+        if DIR_PATH[cntType]  then
+            -- body 
+            opRes,count, desc =  delBaseInfo(cntType, content.id, DIR_PATH[cntType] )
+        else
+            if cntType == "WorkRecord" then
+                -- body
+                opRes,count, desc = delBaseInfo(cntType, content.id, "/sdcard0/"..content.wnum .. "/" .. content.fnum)
+            else
+                opRes,count, desc = delBaseInfo(cntType, content.id, "/sdcard0/"..content.wnum )
+            end
+
+        end
+
+    end
+    if op == "directive" then
+
+        if cntType == "File" then
+            -- body
+            if content.file_name == "/sdcard0/log/0" then
+                -- body
+                opRes = logModuel.readfile(nil)
+            else
+                opRes = logModuel.readfile(content.file_name)
+            end
+        end
+
+        if cntType == "SysCMD" then
+            -- body
+            if content.cmd_content == "Reboot" then
+                -- body
+                opRes = true
+                sys.restart("Sever send reboot CMD! ")
+            end
+            if content.cmd_content == "FormatSD" then
+                -- body
+                local fg = io.format(io.SDCARD)
+                log.info("format res", fg)
+                if fg == 1 then
+                    -- body
+                    nvm.set("localCntVersion", "0")
+                    sys.restart("Server send Format SDcard CMD! ")
+                else
+                    opRes = false
+                    desc = "格式化SDcard失败"
+                end
+                
+            end
+        end
+        if cntType == "Config" then
+            -- body
+            for k,v in pairs(content) do
+                nvm.set(k, v)
+            end
+            opRes = true
+            sys.restart("Sever send config update! ")
+        end
+
+        
+
+    end
+
+    local localVersion = nvm.get("localCntVersion")
+    if cntVersion > localVersion then
+        -- body
+        nvm.set("localCntVersion", cntVersion)
+        log.info("nvm set success, value:", cntVersion)
+    end
+
+    -- log.info("optype:",op,"cntType:", cntType, "opRes:",opRes, "count:",count, "desc:",desc)
+    if not opRes  then
+        -- body
+        if not desc then
+            -- body
+            desc = ""
+        end
+        logModuel.debug_log("mqtt_recieve operate fs failed! desc:"..desc..",optype:"..op..",cntVersion:"..cntVersion)
+
+    end
+
+    return opRes,desc
+end
+
+--- MQTT客户端数据接收处理
+-- @param mqttClient,MQTT客户端对象
+-- @return 处理成功返回true,处理出错返回false
+-- @usage mqttInMsg.proc(mqttClient)
+function proc(mqttClient)
+    local result,data,param
+    while true do
+        result, data, param = mqttClient:receive(30000,"LOCAL_PUB_MSG")
+
+
+        --接收到数据
+        -- opType = "update"时,若不存在,则 add
+
+
+        if result then
+            local resData = json.decode(data.payload)
+
+            local ack = {
+                Imei = misc.getImei(),
+                CntVersion = "",
+                Succ = "",
+                Extra = {}
+            }
+
+            --{"Extra":{},"Succ":"1","Imei":"863488052331447","CntVersion":"1659751519989"}
+            
+
+            local extrTable = {}
+            local hasFile = false
+            for k,v in pairs(resData) do
+                local opRes, desc = operateFs(v.OpType, v.CntType, v.CntVersion, v.Content)
+                if not opRes then
+                    -- body
+                    ack.Succ = "-1"
+                    table.insert(extrTable, "error_version:"..v.CntVersion..",OpType:"..v.OpType..",CntType:"..v.CntType..",desc:"..desc)
+                end
+
+                if v.OpType =="directive" and v.CntType == "File" then
+                    -- body
+                    table.insert(extrTable, "file_name:"..(v.Content.file_name or "unknown_file" )..",content:"..opRes)
+                    hasFile = true
+                end
+            end
+            if ack.Succ == "" then
+                -- body
+                ack.Succ = "1"
+            end
+            ack.CntVersion = nvm.get("localCntVersion")
+            ack.Extra = extrTable
+
+            local mqttSendContent = ""
+            if hasFile then
+                -- body
+                mqttSendContent = '{"Imei":' .. misc.getImei() ..',' .. '"CntVersion":'.. ack.CntVersion .. ',' .. '"Succ":'.. ack.Succ .. ','.. '"Extra":'.. table.concat(extrTable)  .. '}'
+            else
+                mqttSendContent = json.encode(ack)
+            end
+
+            -- log.info("json temple:", att)
+            -- mqttClient:publish("SHEGCL/IntelligenTool/Ack", json.encode(ack))
+            mqttClient:publish("SHEGCL/IntelligenTool/Ack", mqttSendContent) 
+        elseif data == "LOCAL_PUB_MSG" then
+            if type(param) == "string" then
+                -- body
+                param = json.decode(param)
+                if param.topic and param.data then
+                    -- body
+                    local upData = param.data
+                    upData.PublishVersion = nvm.get("localCntVersion")
+                    upData.IMEI = misc.getImei()
+                    mqttClient:publish(param.topic, json.encode(upData))
+                end
+            else
+                log.error("mqtt_recieve.proc", "param type invalid!! param:",param) 
+            end
+        elseif data == "timeout" then
+            log.info("mqtt_recieve.proc", "mqtt wait receive timeout!")
+        else
+            break
+        end
+    end
+	
+    return result or data=="timeout" or data=="LOCAL_PUB_MSG"
+end
+
+
+

+ 28 - 0
otaTask.lua

@@ -0,0 +1,28 @@
+module(...,package.seeall)
+require"nvm"
+local otaUrl = nvm.get("otaUrl")
+local otaCheckInterval = nvm.get("otaCheckInterval")
+--[[
+使用Luat物联云平台的升级服务器时,按照如下步骤操作
+1、在main.lua中定义PRODUCT_KEY变量
+2、加载update模块 require"update"
+3、调用update.request()即可
+]]
+require"update"
+
+local function otaUpdateCb(result)
+    if result then
+        log.info("otaTask.otaUpdateCb","ota update download success, start reboot...")
+        --用新的config.lua覆盖原来的参数文件
+        --nvm.remove()
+        sys.restart("UPDATE_DOWNLOAD_SUCCESS")
+    else
+        sys.publish("ota_update_check_end")
+        log.info("otaTask.otaUpdateCb","ota update download failed!")
+    end
+end
+
+update.request(otaUpdateCb,otaUrl,otaCheckInterval * 1000)
+
+
+sys.timerLoopStart(log.info,30000,"otaTask.timerLoopStart",rtos.get_version(),_G.VERSION,rtos.poweron_reason(),"Flash(Byte):",rtos.get_fs_free_size(),"RAM(KB):", collectgarbage("count"))

+ 104 - 0
powerManage.lua

@@ -0,0 +1,104 @@
+module(...,package.seeall)
+
+require "pins"
+
+local BAT_ADC_ID,DC_ADC_ID = 2,3
+
+local function powerInterrupt( msg )
+    -- body
+    log.info("msg:", msg)
+    if msg==cpu.INT_GPIO_NEGEDGE then
+        log.info("gpio11 INT NEGEDGE msg")
+        sys.publish("24V_POWER_DOWN")
+        modbusTT.checkNetWorkHealth("power_24_off")
+    else
+        log.info("gpio11 INT POSGEDGE msg")
+    end
+end
+
+local setGpio11Fnc = pins.setup(pio.P0_11, powerInterrupt )
+
+function closePDs(  )
+    -- body
+    uart.close(1) --关闭串口1
+    pins.setup(pio.P0_18, 1) --断电GPS
+end
+
+
+local function setRestartClock(  )
+    -- body
+    log.info("alarm test start")
+    local t = os.date("*t")
+    misc.setClock({year=t.year,month=t.month,day=t.day,hour=t.hour,min=t.min,sec=t.sec})
+    sys.wait(2000)
+    closePDs()
+    local onTimet = os.date("*t",os.time() + 3600)  --下次要开机的时间为1800秒后
+    log.info("alarm restart time", 3600)
+    rtos.set_alarm(1,onTimet.year,onTimet.month,onTimet.day,onTimet.hour,onTimet.min,onTimet.sec)   --设定闹铃
+    --如果要测试关机闹钟,打开下面这2行代码
+    sys.wait(200000)
+    rtos.poweroff()
+end
+
+local function powerTaskFnc(  )
+    -- body
+    sys.wait(10000)
+    power24Flag = setGpio11Fnc()
+    log.info("当前24V电平:", power24Flag)
+
+    if power24Flag == 0 then
+        -- body
+        setRestartClock()
+        return
+    end
+
+    sys.waitUntil("24V_POWER_DOWN")
+    power24Flag = setGpio11Fnc()
+    log.info("当前24V电平:", power24Flag)
+
+    
+    log.info("alarm test start")
+    local t = os.date("*t")
+    misc.setClock({year=t.year,month=t.month,day=t.day,hour=t.hour,min=t.min,sec=t.sec})
+    sys.wait(2000)
+    local onTimet = os.date("*t",os.time() + 600)  --下次要开机的时间为1800秒后
+    log.info("alarm restart time", 600) 
+    rtos.set_alarm(1,onTimet.year,onTimet.month,onTimet.day,onTimet.hour,onTimet.min,onTimet.sec)   --设定闹铃
+    --如果要测试关机闹钟,打开下面这2行代码
+    sys.wait(200000)
+    rtos.poweroff()
+end
+
+adc.open(BAT_ADC_ID)
+
+function adcTimer( )
+    -- body
+    local adcval, voltval = adc.read(BAT_ADC_ID)
+    log.info("bat_power.read",adcval,voltval)
+end
+
+sys.timerLoopStart(adcTimer, 10000)
+
+
+sys.taskInit(powerTaskFnc)
+
+
+--[[
+函数名:alarMsg
+功能  :开机闹钟事件的处理函数
+参数  :无
+返回值:无
+]]
+local function alarMsg()
+	print("alarMsg---------------")
+end
+
+--如果是关机闹钟开机,则需要软件主动重启一次,才能启动GSM协议栈
+if rtos.poweron_reason()==rtos.POWERON_ALARM then
+	sys.restart("ALARM")
+end
+
+--注册闹钟模块
+rtos.init_module(rtos.MOD_ALARM)
+--注册闹钟消息的处理函数(如果是开机闹钟,闹钟事件到来时会调用alarmsg)
+rtos.on(rtos.MSG_ALARM,alarMsg)

+ 644 - 0
sdModuel.lua

@@ -0,0 +1,644 @@
+-- pm.wake("sdcard")
+
+local comSize = 4 --每个公共目录下文件大小  单位 kb
+-- 挂载SD卡,返回值0表示失败,1表示成功
+-- local sdcard = io.mount(io.SDCARD)
+-- log.info('mount sd card', sdcard)
+local sdCardTotalSize = rtos.get_fs_total_size(1, 1)
+log.info("sd card total size " .. sdCardTotalSize .. " KB")
+
+local delimiter = '\0'
+
+if io.opendir("/sdcard0/common") then
+    for i=1,100 do
+        local fType,fName,fSize = io.readdir()
+        log.info("fname",fName)
+        if fType==32 then
+            -- log.info("sd card file",fName,fSize)
+        elseif fType == nil then
+            break
+        end
+    end
+    io.closedir("/sdcard0/commmon")
+end
+
+-- 删除目录
+-- local rmfile = rtos.remove_dir('/sdcard0/common')
+-- log.info('delete', rmfile)
+-- rtos.make_dir('/sdcard0/log')
+-- debug_log('写入测试日志')
+-- local del = os.remove(comDir .. '/user')
+-- log.info('del user file', del)
+-- local readval = readfile() -- 参数:完整路径文件名  不传或者传'/sdcard0/log/0'都是获取最新日志文件
+-- print(readval)
+--获取table长度
+function table_leng(t)
+    local leng=0
+    for k, v in pairs(t) do
+      leng=leng+1
+    end
+    return leng;
+  end
+-- 分割字符串
+---@param str string 元字符串
+---@param seq string 分割字符
+---@return table
+function split(str, seq)
+    local nFindStartIndex = 1
+    local nSplitIndex = 1
+    local nSplitArray = {}
+    while true do
+       local nFindLastIndex = string.find(str, seq, nFindStartIndex)
+       if not nFindLastIndex then
+        nSplitArray[nSplitIndex] = string.sub(str, nFindStartIndex, string.len(str))
+        break
+       end
+       nSplitArray[nSplitIndex] = string.sub(str, nFindStartIndex, nFindLastIndex - 1)
+       nFindStartIndex = nFindLastIndex + string.len(seq)
+       nSplitIndex = nSplitIndex + 1
+    end
+    return nSplitArray
+end
+--数组去重
+function table.unique(t, bArray, mainKey)
+    local check = {}
+    local n = {}
+    local idx = 1
+    for k, v in pairs(t) do
+        local judgeKey = v
+        if mainKey then
+            judgeKey = v[mainKey] or v
+        end
+        if not check[judgeKey] then
+            if bArray then
+                n[idx] = v
+                idx = idx + 1
+            else
+                n[k] = v
+            end
+            check[judgeKey] = true
+        end
+    end
+    return n
+end
+--循环创建文件夹
+function createAllFolder(path)
+-- print(path)
+	local path_tb={}
+	local new_path=""
+	-- 分割路径保存到table
+	for i,s in pairs(split(path,'/')) do
+		if s~=nil then
+			table.insert(path_tb,s)
+		end
+	end
+    -- print(json.encode(path_tb))
+	local cdir = false --创建结果
+	-- 遍历并拼接路径检测是否存在,不存在则新建
+	for k,v in ipairs(path_tb) do
+        
+        if v ~= '' then
+            if k==1 then
+                new_path=v
+            else
+                new_path=new_path.."/"..v
+            end		
+            -- print(new_path,io.opendir(new_path))
+            local opflag = io.opendir(new_path)
+            if opflag ~= 1 then
+                cdir = rtos.make_dir(new_path)
+                log.info("path:", new_path, "flag:",cdir)
+            end
+            
+        end
+	end
+    io.closedir()
+    return cdir
+end
+-- 打开sd卡公共目录,不存在则创建 获取最新文件,
+function getComLastFile(dirPath,filename)
+    local lastfile = filename --返回最新文件
+    -- log.info('func:getComLastFile open dir', io.opendir(dirPath))
+    if io.opendir(dirPath) ~= 0 then
+        local file = {} -- 该目录所有文件名
+        for i = 1, 999 do
+            local fType, fName, fSize = io.readdir()
+            -- log.info("file or dir",fType, fName, fSize)
+            if fType == 32 then
+                -- log.info("func getComLastFile common file", fName, fSize)
+                local tname = split(fName,'-')
+                -- log.debug('func:getComLastFile tname',tname,tname[1],tname[2])
+                if tname[1] == filename then
+                    if tname[2] then
+                        table.insert(file,tname[2])
+                    end
+                end
+                -- local c = io.readFile(dirPath..'/'..fName)
+                -- log.info('文件内容',c)
+            elseif fType == nil then
+                break
+            end
+        end
+        -- log.error('files',json.encode(file))
+        --获取文件名后缀最大值
+        local max = nil -- 最新的文件  即数字名称值最大的文件
+        for i, v in pairs(file) do
+            v = tonumber(v) --数组中是string类型   比较会有问题
+            if max == nil then max = v end
+            if max < v then max = v end
+        end
+        -- print(max)
+        if max then
+            -- 判断该最新文件大小
+            local cnt = io.fileSize(dirPath .. '/' .. filename..'-'..max)
+            if cnt then
+                if cnt >= (comSize * 1024) then -- 文件大于设置的文件大小 新建新文件
+                    max = max + 1
+                end
+                lastfile = filename..'-'..max
+            end
+        else
+             -- 判断该最新文件大小
+             local cnt = io.fileSize(dirPath .. '/' .. filename)
+             if cnt then
+                 if cnt >= (comSize * 1024) then -- 文件大于设置的文件大小 新建新文件
+                     lastfile = filename..'-1'
+                 end
+             end
+        end
+        -- print(lastfile)
+        log.debug('func:getComLastFile lastfile',lastfile)
+        io.closedir()
+        return lastfile
+    else
+      local cdir = createAllFolder(dirPath)
+      if cdir then
+          log.info('创建公共目录成功', dirPath)
+      else
+          log.error('创建公共目录失败',dirPath)
+      end
+      return lastfile
+    end
+end
+--根据某个目录下文件名获取该类型所有文件  返回table
+function getAllFiles( dir, file )
+    local fs = {}
+    if not file then
+        return false,'fun:getAllFiles,desc:file not found'
+    end
+    log.error('open dir',io.opendir(dir))
+    if io.opendir(dir) ~= 0 then
+        for i = 1, 999 do
+            local fType, fName, fSize = io.readdir()
+            -- log.info("file or dir",fType, fName, fSize)
+            if fType == 32 then
+                -- log.info("common file", fName, fSize)
+                local tname = split(fName,'-')
+                -- log.debug('func:getAllFiles tname',tname,tname[1],tname[2])
+                if tname[1] == file then
+                    table.insert(fs,fName)
+                end
+            elseif fType == nil then
+                break
+            end
+        end
+    else
+        io.closedir()
+        return false,'fun:getAllFiles,desc:dir not found'
+    end
+    io.closedir()
+    return fs,'fun:getAllFiles,desc:get all files is ok'
+end
+-- 保存基础信息所有扳手信息
+-- 文件 所有扳手信息   查询条件扳手编号 wrench
+-- 文件 所有风场信息 wind
+-- 文件 部件列表 unit
+-- 文件 用户信息  user     查询条件用户名+密码
+-- 文件 任务计划 task      查询条件任务编号
+-- 文件 工作位置列表  workspace  查询条件风机型号+部件号
+-- 文件 待上传信息
+-- 文件 配置信息 比如最后一次使用时间 用于存储空间不够时删除
+--参数[filename]  文件名称 如wrench、wind、unit。。。[data] 保存数据 table类型
+function saveBaseInfo( filename,data,dirPath)
+    -- print(filename)
+    if not filename then
+        log.error('savebaseinfo','filename not fount')
+        return false,'filename not fount'
+    end
+    if not data then
+        log.error('savebaseinfo','data not fount')
+        return false,'data not fount'
+    end
+    if not dirPath then
+        log.error('savebaseinfo','dirPath not fount')
+        return false,'dirPath not fount'
+    end
+    --最新文件名称
+    local filename = getComLastFile(dirPath,filename)
+    log.debug('func:saveBaseInfo last file',filename)
+    local path = dirPath..'/'..filename
+    log.info('save path',path)
+    data = json.encode(data)..delimiter
+    local c = io.writeFile(path,data, "a+b")
+    if c then
+        log.info('write result', c)
+        return true
+    else
+        log.error('error', '基础信息写入失败')
+        return false,'基础信息写入失败'
+    end
+end
+-- 保存基础信息
+-- local wrench = {id=1,name='测试设备'}
+-- local res,desc= saveBaseInfo('wrench',wrench)
+-- log.debug('save result',res,desc)
+-- 模拟数据
+-- for i=113,150 do
+--     local user = {id=i,name='小亮'..i,pwd='49BA59ABBE56E057',time=os.time()}  --password  md5加密 16位大写  123456
+--     local res,desc= saveBaseInfo('user',user,'/sdcard0/wind/12345')
+--     log.debug('save result',res,desc)
+--     break
+-- end
+
+--查询设备信息
+--参数[filename]  文件名称 如wrench、wind、unit。。。[param] 保存数据 table类型 nil查询所有数据
+--返回结果  result 结果 值true/false count--查询文件数量 desc --结果描述
+ function getBaseInfo( filename,param,dirPath)
+    local selectRes = {} --查询结果
+    local count = 0 --查询文件个数
+    if not filename then
+        log.error('func:getBaseInfo','filename not fount')
+        return false,count,'filename not fount'
+    end
+    if not dirPath then
+        log.error('func:getBaseInfo','dirPath not fount')
+        return false,count,'dirPath not fount'
+    end
+    --获取所有该文件及副本文件
+    local files,desc = getAllFiles(dirPath,filename)
+    local filevals = nil --文件内容
+    if not files then
+        return false,count,desc
+    end
+    for i,file in pairs(files) do
+        local path = dirPath..'/'..file
+        local filehandle = io.open(path, "r") -- 第一个参数是文件名,第二个是打开方式,'r'读模式,'w'写模式,对数据进行覆盖,'a'附加模式,'b'加在模式后面表示以二进制形式打开
+        if not filehandle then -- 判断文件是否存在
+            break --不存在 跳过 查询下个文件
+        end
+        fileval = filehandle:read("*all") -- 读出文件内容
+        -- print(fileval)
+        if not fileval then
+                break --空文件 跳过读取下一个文件
+        end
+        local filevaltable = split(fileval,delimiter)
+        local table_length = table_leng(filevaltable)
+        if table_length <= 1 then
+            break --无'-'标识符 跳过读取下一个文件
+        end
+        local isBreak = false
+
+        for a = 1,table_length-1 do
+            local val = json.decode(filevaltable[a])
+
+            if param then --有查询参数
+                local p_length = table_leng(param) --条件长度
+                local succ_cnt = 0; --比较成功个数
+                for p,s in pairs(param) do
+                    if filename == "Users" then
+                        if p == 'pwd' then
+                            s =  string.sub(string.upper(crypto.md5(s,#s,16)),9,24) --密码加密  加密结果32位  取16位(第9-24)字符
+                        end
+                    end
+                    if val[p] == s then
+                        succ_cnt = succ_cnt + 1
+                    else
+                        break
+                    end
+                end
+                if p_length == succ_cnt then --找到结果 停止继续查找下个文件
+                    selectRes[i] = val
+                    isBreak = true
+                    break
+                end
+            else --无查询参数  查询所有
+                selectRes[i] = val
+            end
+        end
+        count = i
+        if isBreak then --找到结果 停止继续查找下个文件
+            break;
+        end
+        filehandle:close() -- 关闭文件
+    end
+    print(table_leng(selectRes),json.encode(selectRes))
+    if table_leng(selectRes) > 0 then
+         --去重
+        local result = table.unique(selectRes,true,'id')
+        return result,count,'select success'
+    else
+        return false,count,'this data is not found'
+    end
+end
+
+-- 查询文件内容复数
+function getBaseInfo_ununique( filename,param,dirPath)
+    local selectRes = {} --查询结果
+    local count = 0 --查询文件个数
+    if not filename then
+        log.error('func:getBaseInfo','filename not fount')
+        return false,count,'filename not fount'
+    end
+    if not dirPath then
+        log.error('func:getBaseInfo','dirPath not fount')
+        return false,count,'dirPath not fount'
+    end
+    --获取所有该文件及副本文件
+    local files,desc = getAllFiles(dirPath,filename)
+    local filevals = nil --文件内容
+    if not files then
+        return false,count,desc
+    end
+    for i,file in pairs(files) do
+        local path = dirPath..'/'..file
+        local filehandle = io.open(path, "r") -- 第一个参数是文件名,第二个是打开方式,'r'读模式,'w'写模式,对数据进行覆盖,'a'附加模式,'b'加在模式后面表示以二进制形式打开
+        if not filehandle then -- 判断文件是否存在
+            break --不存在 跳过 查询下个文件
+        end
+        fileval = filehandle:read("*all") -- 读出文件内容
+        -- print(fileval)
+        if not fileval then
+                break --空文件 跳过读取下一个文件
+        end
+        local filevaltable = split(fileval,delimiter)
+        local table_length = table_leng(filevaltable)
+        if table_length <= 1 then
+            break --无'-'标识符 跳过读取下一个文件
+        end
+        local isBreak = false
+
+        for a = 1,table_length-1 do
+            local val = json.decode(filevaltable[a])
+
+            if param then --有查询参数
+                local p_length = table_leng(param) --条件长度
+                local succ_cnt = 0; --比较成功个数
+                for p,s in pairs(param) do
+
+                    if val[p] == s then
+                        succ_cnt = succ_cnt + 1
+                    else
+                        break
+                    end
+                end
+
+                if p_length == succ_cnt then --找到结果 停止继续查找下个文件
+                    table.insert(selectRes, val)
+                end
+                
+            else --无查询参数  查询所有
+                table.insert(selectRes, val)
+            end
+        end
+        count = i
+        -- if isBreak then --找到结果 停止继续查找下个文件
+        --     break;
+        -- end
+        filehandle:close() -- 关闭文件
+    end
+    print(table_leng(selectRes),json.encode(selectRes))
+    if table_leng(selectRes) > 0 then
+         --去重
+        local result = table.unique(selectRes,true,'id')
+        return result,count,'select success'
+    else
+        return false,count,'this data is not found'
+    end
+end
+
+-- local res,cnt,desc = getBaseInfo('user',{pwd="123456",name="小亮113"},'/sdcard0/wind/12345')
+-- log.info('select result',res,cnt,desc)
+-- for i,j in ipairs(res) do
+--     for m,n in pairs(j) do
+--         print(m,n)
+--     end
+-- end
+--删除基本信息
+--参数[filename]  文件名称 如wrench、wind、unit。。。[id] 删除数据id
+function delBaseInfo(filename,id,dirPath)
+    local res = false --删除结果
+    local count = 0 --查询文件个数
+    log.info("del process:",filename,id,dirPath)
+    if not filename then
+        log.error('func:delBaseInfo','filename not fount')
+        return res,count,'filename not fount'
+    end
+    if not id then
+        log.error('func:delBaseInfo','id not fount')
+        return res,count,'id not fount'
+    end
+    if not dirPath then
+        log.error('func:delBaseInfo','dirPath not fount')
+        return res,count,'dirPath not fount'
+    end
+    --获取所有该文件及副本文件
+    local files,desc = getAllFiles(dirPath,filename)
+    local filevals = nil --文件内容
+    if not files then
+        return res,count,desc
+    end
+    local isCurFile = false --要删除文件是否找到
+    for i,file in pairs(files) do
+        local path = dirPath..'/'..file
+        local filehandle = io.open(path, "r") -- 第一个参数是文件名,第二个是打开方式,'r'读模式,'w'写模式,对数据进行覆盖,'a'附加模式,'b'加在模式后面表示以二进制形式打开
+        if not filehandle then -- 判断文件是否存在
+            break --不存在 跳过 查询下个文件
+        end
+        fileval = filehandle:read("*all") -- 读出文件内容
+        if not fileval then
+            break --空文件 跳过读取下一个文件
+        end
+        local filevaltable = split(fileval,delimiter)
+        local table_lenght = table_leng(filevaltable)
+        if table_lenght <= 1 then
+            break --无'-'标识符 跳过读取下一个文件
+        end
+        local newfileval = "" --删除后文件内容
+        for a = 1,table_lenght-1 do
+            local val = json.decode(filevaltable[a])
+            if val.id ~= id then
+                data = json.encode(val)
+                if newfileval ~= "" then
+                    newfileval = newfileval..data..delimiter
+                else
+                    newfileval = data..delimiter
+                end
+            else
+                isCurFile = true
+            end
+        end
+        filehandle:close() -- 关闭文件
+        if isCurFile then
+            --删除旧文件
+            local del = os.remove(path)
+            log.debug('func:delBaseInfo del file', del)
+            --保存删除后的内容
+            local c = io.writeFile(path,newfileval, "a+b")
+            if c then
+                count = i
+                log.info('func:delBaseInfo save file', c)
+                return true,count,'del success'
+            else
+                log.error('error', '基础信息写入失败')
+                return false,count,'del ok,but save fail'
+            end
+            break
+        else
+            count = i
+        end
+    end
+    if not isCurFile then
+        return false,count,'this data not found where id='..id
+    end
+end
+-- local res,cnt,desc = delBaseInfo('user',113,'/sdcard0/wind/12345')
+-- log.info('del result',res,cnt,desc)
+--修改基本信息
+--参数[filename]  文件名称 如wrench、wind、unit。。。[data] 要修改的数据 table类型 要包含数据id
+--返回结果  result 结果 值true/false count--查询文件数量 desc --结果描述
+function updateBaseInfo( filename,data,dirPath)
+    local res = false --修改结果
+    local count = 0 --查询文件个数
+    if not filename then
+        log.error('func:updateBaseInfo','filename not fount')
+        return res,count,'filename not fount'
+    end
+    if not data.id then
+        log.error('func:updateBaseInfo','data not fount')
+        return res,count,'the id of data is not fount'
+    end
+    --获取所有该文件及副本文件
+    local files,desc = getAllFiles(dirPath,filename)
+    local filevals = nil --文件内容
+    if not files then
+        return res,count,desc
+    end
+    local isCurFile = false --要修改数据文件是否找到
+    for i,file in pairs(files) do
+        local path = dirPath..'/'..file
+        local filehandle = io.open(path, "r") -- 第一个参数是文件名,第二个是打开方式,'r'读模式,'w'写模式,对数据进行覆盖,'a'附加模式,'b'加在模式后面表示以二进制形式打开
+        if not filehandle then -- 判断文件是否存在
+            break --不存在 跳过 查询下个文件
+        end
+        fileval = filehandle:read("*all") -- 读出文件内容
+        if not fileval then
+            break --空文件 跳过读取下一个文件
+        end
+        local filevaltable = split(fileval,delimiter)
+        local table_length = table_leng(filevaltable)
+        if table_length <= 1 then
+            break --无'-'标识符 跳过读取下一个文件
+        end
+        local newfileval = nil --删除后文件内容
+        for a = 1,table_length-1 do
+            local val = json.decode(filevaltable[a])
+            if val.id ~= data.id then --过滤要修改的那条数据
+                dataStr = json.encode(val)
+                if newfileval then
+                    newfileval = newfileval..dataStr..delimiter
+                else
+                    newfileval = dataStr..delimiter
+                end
+            else
+                --将新数据放入新的文件内容中
+                local newData = json.encode(data)
+                if newfileval then
+                    newfileval = newfileval..newData..delimiter
+                else
+                    newfileval = newData..delimiter
+                end
+                isCurFile = true
+            end
+        end
+        filehandle:close() -- 关闭文件
+        if isCurFile then
+           if newfileval then
+                --删除旧文件
+                local del = os.remove(path)
+                if not del then
+                    return false,count,'func:updateBaseInfo del fail,please reoperate'
+                end
+                --保存删除后的内容
+                local c = io.writeFile(path,newfileval, "a+b")
+                if c then
+                    count = i
+                    return true,count,'func:updateBaseInfo update success'
+                else
+                    return false,count,'func:updateBaseInfo del success,but save fail'
+                end
+            else
+                return false,count,'the file content after del create fail'
+            end
+            break
+        else
+            count = i
+        end
+    end
+    if not isCurFile then
+        return false,count,'this data not found where id='..data.id
+    end
+end
+
+
+
+sys.taskInit(function()
+    -- while true do
+    --     log.info("test00")
+    --     led.blinkPwm(blueLed,2000,1000)
+    --     led.blinkPwm(redLed,3000,1000)
+
+        
+    --     sys.wait(2000)
+    -- end
+
+    sys.wait(5000)
+
+    local moutedFlag = io.mount(io.SDCARD)
+    log.info('mount sd card', moutedFlag)
+    
+
+
+
+    local sdCardTotalSize = rtos.get_fs_total_size(1,1)
+    log.info("sd card total size "..sdCardTotalSize.." KB")
+    
+    if moutedFlag == 1 then
+        -- body
+        sys.publish("IO_SDCARD_MOUTED")
+    end
+
+end)
+
+
+-- saveBaseInfo("test", {id=1, name="test", time=os.time()}, "/sdcard0/test")
+    -- local user = {id=112,name='小亮xxx',pwd='49BA59ABBE56E057',time=os.time()}  --password  md5加密 16位大写  123456
+    -- local res,desc= updateBaseInfo('user',user,'/sdcard0/wind/12345')
+    -- log.debug('update result',res,desc)
+-- local del = os.remove(comDir .. '/user-1')
+-- log.info('del user file', del)
+-- local del = os.remove(comDir .. '/user-2')
+-- log.info('del user file', del)
+-- local del = os.remove(comDir .. '/user-3')
+-- log.info('del user file', del)
+-- local del = os.remove(comDir .. '/user-4')
+-- log.info('del user file', del)
+-- local del = os.remove(comDir .. '/user-5')
+-- log.info('del user file', del)
+-- local del = os.remove(comDir .. '/user-6')
+-- log.info('del user file', del)
+-- local del = os.remove(comDir .. '/user-8')
+-- log.info('del user file', del)
+-- local del = os.remove(comDir .. '/user')
+-- log.info('del user file', del)
+-- sys.init(0, 0)
+-- sys.run()