--[[*****************************Copyright(c)**********************************
**                Guangzhou DACAIGAUNGDIAN Technology Co. Ltd
**
**                             http://www.gz-dc.com
**
**------File Info-----------------------------------------------------------
** File Name:                main.lua
** Latest modified Date:    2020/08/21
** Latest Version:            
** Description:                4G例程，功能包括：4G模块初始化；获取天气、时间；获取运营商、信号强度；
**                          HTTP下载大文件并保存到屏的内存中；MQTT连接Aliyun；
**
**--------------------------------------------------------------------------
** Created By:                林绍佳
** Created date:            2020/08/21
** Version:                    V1.0    
** Descriptions:            4G例程，功能包括：4G模块初始化；获取天气、时间；获取运营商、信号强度；
**                          HTTP下载大文件并保存到屏的内存中；MQTT连接Aliyun；
**
**--------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
***************************************************************************--]]

--[[
--使用PC虚拟串口屏调试4G模块时使用
--屏幕需要升级工程 UART3_TO_UART1
--使用虚拟屏与实体屏联调时，设置air_debug_mode = 1
--使用实体屏运行时，设置air_debug_mode = 0
--]]
local air_debug_mode = 0
--uart_free_protocol = 1      --自由串口协议

local enbit_http_getwea = 0


--下载完成后显示图片
local surface=0         --图片显示的全局变量，必须写上
local picture_en=0      --绘图使能


--定时获取天气和信号强度的回调函数的定时器
local timerId_Sig_Weather = 2
--local timer0_notify_cnt   = 0

screen_wifi_set = 21
screen_search_wifi = 22

local dl_reset_flag=0             --http下载文件错误处理，重启

--测试计时器
local sys_timer_en=0

--生产测试的复位功能标志位
local test_reset_bit = ''
local reset_4G_READY = 0

--当前选中的wifi的名称和密码
local cwifi_ssid = 0
local cwifi_pwd  = 0

--[[***************************************************************************
** Function name:  my_esp_log
** Descriptions:   打印虚拟屏调试信息，设置 en_debug_msg = 1
                   注意：实体屏运行时， en_debug_msg 不能等于 1
***************************************************************************--]]
local en_debug_msg = 0 --0-不显示调试信息;1-虚拟屏; 2-实体屏，串口1输出
function my_esp_log(debug_msg)
    if en_debug_msg == 1
    then
        print(debug_msg)
    elseif en_debug_msg == 2
    then
        uart_send_string(debug_msg)
        uart_send_string('\r\n')
    end
end

--[[***************************************************************************
** Function name:  on_esp_log_cb
** Descriptions:   4G模块-调试信息输出
***************************************************************************--]]
function on_esp_log_cb(msg)
    --数据打印到记录控件
    --record_add(21,6,string.sub(msg,1,100))
end

--[[***************************************************************************
** Function name:  on_init
** Descriptions:   系统初始化时，执行此回调函数。
                   注意：回调函数的参数和函数名固定不能修改
***************************************************************************--]]
function esp32_init()
    
    esp_set_callback(on_esp_send_cb,on_esp_resp_callback,on_esp_log_cb)     --设置4G库函数的命令发送函数，命令回调函数、调试信息打印函数
    esp32_int_mode(1)
    search_wifi_clear()
    
end

function on_esp32_init_cb(key, value) 
    my_esp_log('on_esp32_init_cb key:'..key..',value:'..value)
    if string.find(key,'+CWMODE=1') ~= nil and string.find(value,'OK') ~= nil 
    then
        search_wifi_clear()
        esp32_search_wifi()
        search_wifi_num = 0
    end
end

function search_wifi_clear()
    for i=1,10
    do
        set_text(screen_search_wifi,i,'')
    end
end

local search_wifi_num = 0
--+CWLAP:(4,"RD",-52,"08:9b:4b:9d:c8:ed",1,-1,-1,4,4,7,0)
function on_search_wifi_cb(key, value) 
    my_esp_log('on_search_wifi_cb key:'..key..',value:'..value)
--local regular_e = '+ICCID: (%d*)'                       --正则表达式
--local my_iccid = string.match( value, regular_e)        --获取的值赋给 my_iccid 
    
    if string.find(key,'+CWLAP') ~= nil and string.find(value,'CWLAP:') ~= nil 
    then
        local regular_e = '.*CWLAP:[(0-9]*,"(.*)",[-0-9]*,".*",.*'                       --正则表达式
        local my_wifi_ssid = string.match( value, regular_e)        --获取的值赋给 my_iccid 
        my_esp_log('my_wifi_ssid :'..my_wifi_ssid)
        set_text(screen_search_wifi,1+search_wifi_num,my_wifi_ssid)
        
        local regular_e2 = '.*CWLAP:[(0-9]*,".*",([-0-9]*),".*",.*'                       --正则表达式
        local my_wifi_rssi = string.match( value, regular_e2)        --获取的值赋给 my_iccid 
        my_esp_log('my_wifi_rssi :'..my_wifi_rssi)
        set_text(screen_search_wifi,101+search_wifi_num,my_wifi_rssi)
        
        search_wifi_num = search_wifi_num + 1
    end
    
end

function on_connect_ap_cb(key, value) 
    my_esp_log('on_connect_ap_cb key:'..key..',value:'..value)
    if string.find(key,'+CWJAP') ~= nil and string.find(value,'OK') ~= nil 
    then
        my_esp_log('sus:wifi connect ok')
        esp32_sta_ip()
        set_text(screen_wifi_set,1,'已连接')
        set_text(screen_wifi_set,3,cwifi_ssid)
    end
    if string.find(key,'+CWJAP') ~= nil and string.find(value,'ERROR') ~= nil 
    then
        my_esp_log('error:wifi connect error')
        
        set_text(screen_wifi_set,1,'连接失败')
        set_text(screen_wifi_set,3,'')
    end
end

function on_sta_ip_cb(key, value)
    my_esp_log('on_sta_ip_cb key:'..key..',value:'..value)
    if string.find(key,'+CIPSTA') ~= nil and string.find(value,'+CIPSTA:ip') ~= nil 
    then
        local regular_e = '+CIPSTA:ip:"(.*)"'                       --正则表达式
        local my_sta_ip = string.match( value, regular_e)        --获取的值赋给 my_iccid
        set_text(screen_wifi_set,2,my_sta_ip)
    end
    
end

--[[***************************************************************************
** Function name:  on_timer
** Descriptions:   定时器超时回调
***************************************************************************--]]
function on_esp32_timer(timer_id)
    on_espat_timer(timer_id)                                  --4G库函数的定时处理
end

--[[***************************************************************************
** Function name:  on_esp_send_cb
** Descriptions:   4G模块-发送数据
***************************************************************************--]]
function on_esp_send_cb(msg)
    if air_debug_mode==1  
    then
        uart_send_string(msg)                       -- air_debug_mode==1 ，使用虚拟屏调试，通过串口1发送数据
        my_esp_log(msg)
    else
        uart_send_string3(msg)                      -- air_debug_mode==0 ，使用实体屏调试，通过串口3发送数据
        --my_esp_log('out: '..msg..'\r\n')
    end
end

function on_esp_resp_callback(key,value)

end


-----HTTP下载回调 start----
--下载文件的全局变量------
local down_file          = nil  --虚拟盘调试使用，保存数据到C盘
local file_len           = 0    --文件总大小

--分段写入：数据写入文件的全局变量----------
local data_len          = 0       --数据总长度
local WriteOnceSize     = 2048    --单次写数据的长度
local write_begin       = 0       --单次写数据的开始位
local write_end         = 0       --单次写数据的结束位
local write_break_value = {}      --单次写的数据缓存
local open_state        = 0       --文件句柄

local FA_OPEN_EXISTING = 0x00
local FA_READ          = 0x01     --读
local FA_WRITE         = 0x02     --写
local FA_CREATE_NEW    = 0x04     --创建新文件
local FA_CREATE_ALWAYS = 0x08     --覆盖创建新文件
local FA_OPEN_ALWAYS   = 0x10     --打开
local add_write        = FA_WRITE|FA_READ           --写模式
local over_write       = FA_CREATE_ALWAYS|FA_WRITE  --创建文件

--数据写入文件的全局变量 end------

local sd_dir                  = ''    -- SD卡路径，调试时写入SD卡
local down_mode               = 0     -- 下载模式，0-下载图片、1-视频、2-音频
local httpDown_dl_process     = {'正在下载图片...','正在下载视频...', '正在下载音乐...'}
local httpDown_dl_process_end = {'图片名称：car.jpg','视频名称：car.mp4', '音乐名称：mydream.mp3'}
local HttpDownSave_FileTb     = {'3:/car.jpg','3:/car.mp4', '3:/mydream.mp3'}
local HttpDownFile_URITb      = {'http://video.gz-dc.com/logo_480320_165kV2.jpg',
                                 'http://video.gz-dc.com/video2_62M9s.mp4',
                                 'http://video.gz-dc.com/music503k32s.mp3'}

--[[***************************************************************************
** Function name: my_esp_getdataLen_Type
** Descriptions : 获取待写入数据的数据类型和长度
** @data        : 代写入的数据
** @return      : datalen,数据大小; data_type,数据类型
***************************************************************************--]]
function my_esp_getdataLen_Type(data)
    my_esp_log('---------- my_esp_getdataLen_Type ----------'..' \r\n')
    local datalen = -1
    local data_type = type(data)        --获取数据类型
    
    --计算数据长度
    --字符串类型
    if data_type == 'string'
    then
        datalen = string.len(data)      --如果数据类型时string，计算字符串的长度
        
    --表/数组类型
    elseif data_type == 'table'
    then
        datalen = #(data) + 1           --如果数据类型时table，计算表的长度
    end
    
    my_esp_log('Lua_debug data Type and Len: '..data_type..' / '..datalen..' \r\n')
    return datalen,data_type
end


--[[***************************************************************************
** Function name : my_esp_write_filedata
** Descriptions  : 数据分段写入文件
** @file         : 文件路径
** @data         : 待写入的数据
** @open_mode    : 打开文件的方式
** @return       : nil,无返回值
***************************************************************************--]]
function my_esp_write_filedata(file, data, open_mode)
    my_esp_log('---------- my_esp_write_filedata ----------'..' \r\n')
    my_esp_log('Lua_debug: file -> '..file..' / data -> '..type(data)..' / open_mode -> '..open_mode..' \r\n')
    
    local count     = 0     --每次写的字节数
    local write_cnt = 0     --‘data’数据一共需要写的次数
    local seek_ops  = 0     --写位置
    local all_byte  = 0     --获取当前文件大小,仅在追加文件末尾写入执行
    
    --获取待写入数据的长度和数据类型
    local wrire_len, data_type = my_esp_getdataLen_Type(data)
    
    local write_byte_Tb = {}

    --open_state == true 表示文件已打开
    if open_state == true
    then
        --获取当前文件大小,仅在追加文件末尾写入执行
        if open_mode == add_write
        then
            all_byte = file_size()
        end
        
        --数据长度大于0
        if wrire_len > 0
        then
            --计算'@data'要写多少次
            write_cnt =  math.modf(wrire_len / WriteOnceSize)
            -- wrire_len 不是 WriteOnceSize 的整数倍时，wrire_len = wrire_len + 1
            if wrire_len % WriteOnceSize > 0
            then
                write_cnt = write_cnt + 1
            end
            my_esp_log('Lua_debug: need write allcnt -> '..write_cnt..' \r\n')
            
            
            for i = 1, write_cnt
            do
                --复位写字节数组
                write_byte_Tb = {}
                
                --计算写的位置
                seek_ops = (i - 1) * WriteOnceSize +all_byte
                
                --显示当前写入（下载）进度
                http_download_process( seek_ops )
                
                --文件偏移失败
                file_seek(seek_ops)
                if offst_result == false 
                then
                    break
                end
                my_esp_log('Lua_debug: cur seek_ops  -> '..seek_ops..' \r\n')
                
                --计算本次写的个数
                count = WriteOnceSize
                if i == write_cnt
                then
                    if wrire_len % WriteOnceSize > 0
                    then
                        --最后一次写入时，count为剩余数据的长度
                        count = wrire_len % WriteOnceSize
                    end
                end
                my_esp_log('Lua_debug: cur write  -> '..i..'th / wrire count '..count..' \r\n')
                
                --填充写入flash的字节数组
                for j = 0, count - 1
                do
                    if data_type == 'string'
                    then
                        --字符串类型，将每个字符转换为字节数组
                        write_byte_Tb[j - 1] = tonumber(string.byte(data, ((i - 1) * WriteOnceSize + j), ((i - 1) * WriteOnceSize + j)))
                        
                    elseif data_type == 'table'
                    then
                        --数组类型，字节赋值
                        write_byte_Tb[j] = data[((i - 1) * WriteOnceSize + j)]
                    end
                end
                
                flush_flash()                                       --写优化
                local IswriteOK = file_write(write_byte_Tb)         --写数据到文件中
                if IswriteOK == false
                then
                    --写入文件失败，当前数据再写一次
                    i = i - 1
                end    
            end
        end
    else
        --open_state == fail 表示打开失败
        
    end
end

--[[***************************************************************************
** Function name: http_download_process
** Descriptions : 计算当前写入（下载）进度
** @cur_process : 当前下载进度
** @return      : nil, 无返回值
***************************************************************************--]]
function http_download_process( cur_process )
   
    local allsize =  string.format('%0.2f', (file_len    / 1024))
    local cursize =  string.format('%0.2f', (cur_process / 1024))
    local file_curt_dl_perct = (cur_process/file_len)*100
    
    file_curt_dl_perct = tonumber( string.format('%0.1f',file_curt_dl_perct) )

    set_value(screen_mmedia_dl, 6, file_curt_dl_perct)
    set_text(screen_mmedia_dl , 7, '下载进度: '..file_curt_dl_perct..' %')
    set_text(screen_mmedia_dl , 8, '文件大小: '..cursize..' KB / '..allsize..' KB')
end

--[[***************************************************************************
** Function name: on_esp_http_download_file_cb
** Descriptions : 下载文件
** @key         : key, 屏幕    -> 4G模块的请求指令
** @value       : value,4G模块 -> 屏幕  的应答数据 
** @return      : nil, 无返回值
***************************************************************************--]]
function on_esp_http_download_file_cb(key, value)
    my_esp_log(key)
    my_esp_log('on_esp_http_download_file_cb key: '..key..'\r\n')
    
    if key=='data_len' then
        file_len = value                                                        --获取文件长度
        open_state = file_open( HttpDownSave_FileTb[down_mode], over_write)     --创建文件
        if open_state~=true
        then
            uart_send_string(' open_state~=true\r\n ')
        else
            uart_send_string(' open_state==true\r\n ')
        end
        start_timer_download_speed(file_len)                                 --开始计算下载时间
        set_text( screen_mmedia_dl, 4, '')                                      --速度显示为空
    
    elseif key=='data'  --文件数据包   
    then
        my_esp_write_filedata(HttpDownSave_FileTb[down_mode],value,add_write)     --分段写入数据
    
    elseif key=='finish' --下载结束
    then
        --down_file:close()
        start_timer(timerId_Sig_Weather, 5*1000 , 0, 0)                         --重新开启自动获取天气和信号强度功能
        file_close()                                                            --关闭文件
        file_len           = 0
        file_current_dl    = 0
        file_curt_dl_perct = 0
        set_value( screen_mmedia_dl, 6, 0)                                      --初始化进度条数值
        set_text( screen_mmedia_dl, 7, '下载进度：0%')                          --初始化进度文本数值
        set_text( screen_mmedia_dl , 8, '')
        set_visiable( screen_mmedia_dl, 6, 0)                                   --设置进度条不可见
        set_visiable( screen_mmedia_dl, 7, 0)                                   --设置进度文本不可见
        set_visiable( screen_mmedia_dl, 8, 0)                                   --设置文件大小文本不可见
        local dl_sec,dl_speed = stop_timer_download_speed()                     --停止下载计时，比返回总用时秒数，每秒下载速度
        set_text(screen_mmedia_dl,4,'下载速度：'..string.format('%0.2f',dl_speed)..'KB/s 总用时：'..dl_sec..'s ')
        air_set_baudrate(115200)                                                --重新设置4G模块和串口3波特率为115200
        
        --下载模式为1时显示图片
        if down_mode == 1
        then
            set_text(screen_mmedia_dl,5,httpDown_dl_process_end[down_mode])
            if surface ~= 0 
            then
                destroy_surface(surface) 
                surface = 0
            end
            picture_en=1
            surface = load_surface(HttpDownSave_FileTb[down_mode])
            redraw()
        
        --下载模式为2时播放视频
        elseif down_mode == 2
        then
            set_text(screen_mmedia_dl,5,httpDown_dl_process_end[down_mode])
            picture_en = 0
            stop_video()
            play_video(HttpDownSave_FileTb[down_mode], 40, 75, 480, 320)
            
        --下载模式为3时播放音乐
        elseif down_mode == 3
        then
            set_text(screen_mmedia_dl,5,httpDown_dl_process_end[down_mode])
            set_visiable(screen_mmedia_dl, 9, 1)                                --设置音乐图标显示
            picture_en = 0
            stop_video()
            stop_sound()
            play_sound(HttpDownSave_FileTb[down_mode])
        end
        
        set_value(screen_mmedia_dl    , 1, 0)
        set_value(screen_mmedia_dl    , 2, 0)
        set_value(screen_mmedia_dl    , 3, 0)
        set_enable(screen_mmedia_dl   , 1, 1)
        set_enable(screen_mmedia_dl   , 2, 1)
        set_enable(screen_mmedia_dl   , 3, 1)
   
    elseif key=='timeout' --下载超时
    then
        start_timer(timerId_Sig_Weather, 5*1000 , 0, 0)
        
        reset_4G()
        set_text( screen_mmedia_dl, 5, '下载超时，发生网络错误，重新设置中...')              --提示
        dl_reset_flag = 1
        
        air_set_baudrate(115200)                                                --重新设置4G模块和串口3波特率为115200
        stop_timer_download_speed()                                             --停止下载计时
    elseif key=='dl_file_read_retry' -- HTTPREAD 重下
    then
        --**********************************************************************
        --value：            retry: -1,601
        --要提取的值：       -1
        --                   601
        --正则表达式：       'retry: (%d*),(%d*)'
        --**********************************************************************
        local httpread_retry=''
        local status=''
        local regular_e = 'retry: (.*),(%d*)'                                  --正则表达式
        local httpread_retry,status = string.match(value,regular_e)             --获取的值赋给 
        air_log('user r retry: '..httpread_retry..','..status)
        if httpread_retry == '-1' and ( status == '408' or status == '601' or status == '603' )
        then
            reset_4G()
            set_text( screen_mmedia_dl, 5, '下载超时，发生网络错误，重新设置中...')          --提示
            dl_reset_flag = 1
        end
        air_set_baudrate(115200)                                                --重新设置4G模块和串口3波特率为115200
    elseif key=='dl_file_head_retry' -- HTTPHEAD 重下
    then
        --**********************************************************************
        --value：            retry: -1,601
        --要提取的值：       -1
        --                   601
        --正则表达式：       'retry: (%d*),(%d*)'
        --**********************************************************************
        local httphead_retry=''
        local status=''
        local regular_e = 'retry: (.*),(%d*)'                                  --正则表达式
        local httphead_retry,status = string.match(value,regular_e)             --获取的值赋给 
        air_log('user h retry: '..httpread_retry..','..status)
        if httphead_retry == '-1' and ( status == '408' or status == '601' or status == '603' )
        then
            reset_4G()
            set_text( screen_mmedia_dl, 5, '下载超时，发生网络错误，重新设置中...')          --提示
            dl_reset_flag = 1
        end
        air_set_baudrate(115200)                                                --重新设置4G模块和串口3波特率为115200
    end
end

--[[***************************************************************************
** Function name: on_esp32_draw
** Descriptions : 绘图函数
** @screen      : 当前页面
** @return      : nil,无返回值  
***************************************************************************--]]
function on_esp32_draw(screen)
    
    --显示下载的图片
    if screen == screen_mmedia_dl and picture_en==1 
    then
        --my_esp_log("Lua:debug >>> my_draw_sddisk_pic_and_name()\r\n")
        local show_x = 40
        local show_y = 75
        local show_w = 480 
        local show_h = 320
        local crop_x = 0
        local crop_y = 0
        draw_surface(surface, show_x, show_y, show_w, show_h, crop_x, crop_y)
    end
end

--[[***************************************************************************
** Function name: on_esp32_video_notify
** Descriptions : 视频回调函数
** @msg         : 播放通知，0-播放完，1-播放中
** @v1          : 当前播放时间，单位s，秒
** @v2          : 播放文件的总时间，单位s，秒  
** @return      : nil,无返回值 
***************************************************************************--]]
function on_esp32_video_notify(msg,v1,v2)
    my_esp_log("Lua_debug : video notify msg -> "..msg.."  /  v1:v2 = "..v1..":"..v2)
    
    local token_time = ':'
    if msg == 1
    then
        local v1_h = string.format("%02d", math.modf(v1/60/60))
        local v1_m = string.format("%02d", math.modf((v1/60) % 60))
        local v1_s = string.format("%02d", math.modf(v1%60))
        local show_v1 = v1_h..token_time..v1_m..token_time..v1_s
        
        local v2_h = string.format("%02d", math.modf(v2/60/60))
        local v2_m = string.format("%02d", math.modf((v2/60) % 60))
        local v2_s = string.format("%02d", math.modf(v2%60))
        local show_v2 = v2_h..token_time..v2_m..token_time..v2_s

        --set_value(sc_video, 8, (v1/v2)*1000)
        --set_text(sc_video,  9, show_v1)
        --set_text(sc_video, 10, show_v2)
    elseif msg == 0
    then 
        --set_value(screen_mmedia_dl, 8, 0)
        --set_text(screen_mmedia_dl,  9, '')
        --set_text(screen_mmedia_dl, 10, '')
        play_video(HttpDownSave_FileTb[2], 40, 75, 480, 320)
    end
end

--[[***************************************************************************
** Function name: on_audio_callback
** Descriptions : 音乐回调函数
** @state       : 保留
** @return      : nil, 无返回值
***************************************************************************--]]
function on_esp32_audio_callback(state)
    play_sound(HttpDownSave_FileTb[down_mode])
end

----获取时间-----
--[[***************************************************************************
** Function name:  on_get_time_cb
** Descriptions :  获取时间回调函数
** @key         :  屏幕->4G模块的发送请求
** @value       :  4G模块->返回的数据
** @return      :  nil,无返回值
***************************************************************************--]]
function on_get_time_cb(key, value)
    
    my_esp_log('on_get_time_cb key:'..key)
    my_esp_log('on_get_time_cb key:'..key..'\r\n')
    
    --**********************************************************************
    --value：            {"sysTime2":"2020-08-15 14:52:12","sysTime1":"20200815145212"}
    --要提取的值：       2020-08-15 14:52:12
    --对应正则表达式：       '"sysTime2":"(%d*)-(%d*)-(%d*) (%d*):(%d*):(%d*)"' 
    --**********************************************************************
    local string_time_ball=''
    local get_year, get_mon, get_day, get_hour, get_min, get_sec = 0
    local regular_e = '"sysTime2":"(%d*)-(%d*)-(%d*) (%d*):(%d*):(%d*)"'                    --正则表达式
    
    if key=='data' 
    then
        string_time_ball = table2str(value)                                              --表转换为字符串
        get_year, get_mon, get_day, get_hour, get_min, get_sec = string.match( string_time_ball, regular_e)--获取字符串中的时间
        set_date_time(get_year, get_mon, get_day, get_hour, get_min, get_sec)
    end
end

--[[***************************************************************************
** Function name: http_get_time
** Descriptions : 获取时间
** @return      : nil,无返回值
**                可以使用 'AT+CIPGSMLOC=1,1' 指令获取大致的北京时间，此方法得到的时间有可能有误差
***************************************************************************--]]
function http_get_time()
    my_esp_log('http_get_time()')
    air_http_get(
        'http://quan.suning.com/getSysTime.do',
        on_get_time_cb)
end
----获取时间 end-----




--[[***************************************************************************
** Function name : my_find_ChinaShi
** Descriptions  : 转换城市名（UTF-8），如“广州市”转换为“广州”
** CityAddr      : 城市名，如“广州市”
** @return       : 城市名，如“广州”
***************************************************************************--]]
function my_find_ChinaShi(CityAddr)
   
    local strlen = string.len(CityAddr)
    local find_data  = 0
    local new_CityAddr = CityAddr
    
    for i = (strlen - 3), strlen
    do
        find_data = (find_data << 8) | string.byte(CityAddr, i, i)   --转换城市名字符串为16进制数
    end
    
    if (find_data & 0xFFFFFF) == 0xE5B882
    then
        new_CityAddr = string.sub(CityAddr, 1, (strlen - 3))    --转换城市名
    end
    
    return new_CityAddr
end

--[[***************************************************************************
** Function name:  baiduAPI_get_local_cb
** Descriptions:   baiduAPI请求的回调函数
**
**返回实例：
**string_time_ball:{"status":0,"result":{"location":{"lng":113.44028348580408,"lat":23.16279264489196},"formatted_address":"骞夸笢鐪佸箍宸炲競榛勫煍鍖哄瘜搴疯タ琛?0鍙?115","business":"绉戝?﹀??灏忔柊濉?,"addressComponent":{"country":"涓?鍥?","country_code":0,"country_code_iso":"CHN","country_code_iso2":"CN","province":"骞夸笢鐪?,"city":"骞垮窞甯?,"city_level":2,"district":"榛勫煍鍖?,"town":"","town_code":"","adcode":"440112","street":"瀵屽悍瑗胯??","street_number":"10鍙?115","direction":"闄勮繎","distance":"28"},"pois":[],"roads":[],"poiRegions":[],"sematic_description":"","cityCode":257}}
***************************************************************************--]]
function baiduAPI_get_local_cb(key,value)
    my_esp_log('tcp_baiduAPI_get_local_cb key:'..key)
    my_esp_log('on_get_time_cb key:'..key..'\r\n')
    
    local string_time_ball=''
    
    if key=='data' then
        string_time_ball = table2str(value)                                 --表转换为字符串
        local jsondata = cjson.decode(string_time_ball)                     --json解析
            
        local local_city = jsondata['result']['addressComponent']["city"]   --提取表里的城市名（UTF-8）
        local_city = my_find_ChinaShi(local_city)                         --转换城市名
        http_get_wea_and_time(local_city)                                  --获取指定城市的天气和北京时间
    end
end
------------百度API通过IP获取地址 end-----

--推荐在网络上购买付费的天气API，如https://www.tianqiapi.com/index/doc?version=v61
--免费天气API，如https://www.tianqiapi.com/index/doc?version=v6
--xue、lei、shachen、wu、bingbao、yun、yu、yin、qing
local wea = { ['unknow']=0, ['xue']=1, ['lei']=2, ['shachen']=3, ['wu']=4, ['bingbao']=5, ['yun']=6,
                ['yu']=7, ['yin']=8, ['qing']=9, ['yunnight']=10, ['qingnight']=11 }
local wea_chinese = { ['unknow']='未知', ['xue']='雪', ['lei']='雷', ['shachen']='沙尘暴', ['wu']='有雾',
                    ['bingbao']='冰雹', ['yun']='多云', ['yu']='下雨', ['yin']='阴天', ['qing']='晴天',
                     ['yunnight']='多云', ['qingnight']='晴天' }
                  
--[[***************************************************************************
** Function name:  on_get_wea_cb
** Descriptions:   获取指定城市的天气和北京时间的回调函数
***************************************************************************--]]   
function on_get_wea_cb(key,value)
    my_esp_log('on_get_wea_cb key:'..key)
    my_esp_log('on_get_wea_cb key:'..key..'\r\n')
    local jsonstring_wea_ball=''
    local jsondata_string = ''
    local city,wea_img,tem = 0,0,0
    
    if key=='data' then
        jsonstring_wea_ball = table2str(value)                  --表转换为字符串
        local jsondata = cjson.decode(jsonstring_wea_ball)      --解析JSON数据
        city = jsondata.city                                    --获取城市，UTF8编码
        wea_img = jsondata.wea_img                              --获取天气
        tem = jsondata.tem                                      --获取温度
        set_text(screen_main,7,city)                            --显示城市名（UTF-8）
        set_value(screen_main,10,wea[wea_img])                  --设置天气图标
        yearwea,monwea,daywea,hourwea,minwea,secwea,weekwea = get_date_time()  ---获取当前时间用于显示晚上的图标
        if wea_img == 'yun' or wea_img == 'qing' 
        then
            if hourwea <= 6 or hourwea >= 19 
            then
                if wea_img == 'yun' 
                then
                    set_value(screen_main,10,wea['yunnight'])   --显示晚上多云的图标
                end
                if wea_img == 'qing' 
                then
                    set_value(screen_main,10,wea['qingnight'])  --显示晚上晴的图标
                end
            end
        end
        set_text(screen_main,9,wea_chinese[wea_img])            --设置天气中文名称
        set_text(screen_main,8,tem)                             --设置温度
        set_text(screen_main,16,'')
        set_visiable(screen_main, 16, 0)
    end
end

--[[***************************************************************************
** Function name : on_control_notify
** Descriptions  : 系统回调函数，用户通过触摸修改控件后，执行此回调函数。
**                 点击按钮控件，修改文本控件、修改滑动条都会触发此事件。
** @return       : nil,无返回值
***************************************************************************--]]
function on_esp32_control_notify(screen,control,value)
    

    
    --***************************************************************************
    --位置：    多媒体下载
    --***************************************************************************
    -- if screen == screen_mmedia_dl 
    -- then
        -- if (control >= 1 and control <= 3) and value == 1
        -- then
            -- stop_sound()
            -- stop_video()
            
            -- set_enable( screen_mmedia_dl, 1, 0)
            -- set_enable( screen_mmedia_dl, 2, 0)
            -- set_enable( screen_mmedia_dl, 3, 0)
            
            -- set_value( screen_mmedia_dl, 6, 0)
            -- set_text( screen_mmedia_dl , 7, '')
            -- set_text( screen_mmedia_dl , 8, '')
            -- set_text( screen_mmedia_dl, 4, '')
            
            -- set_visiable( screen_mmedia_dl, 6, 1)           --设置进度条可见
            -- set_visiable( screen_mmedia_dl, 7, 1)           --设置进度文本可见
            -- set_visiable( screen_mmedia_dl, 8, 1)           --设置文件大小文本可见
            
            -- set_visiable( screen_mmedia_dl, 9, 0)            --设置音乐图标隐藏
            
            -- picture_en = 0
            -- file_len           = 0
            -- file_current_dl    = 0
            -- file_curt_dl_perct = 0
            
            -- air_set_baudrate(921600)
            -- down_mode = control
            -- set_text( screen_mmedia_dl, 5, httpDown_dl_process[down_mode])
            -- stop_timer( timerId_Sig_Weather)                 --停止自动获取天气、时间、信号强度
            
            ----开始下载
            -- air_http_download(HttpDownFile_URITb[down_mode], 
                              -- 7168,
                              -- on_esp_http_download_file_cb)
        
        ----退出界面时停止播放视频或音频
        -- elseif control == 111 and value == 0
        -- then
            -- stop_sound()
            -- stop_video()
        -- end
    -- end
    
    if screen == screen_wifi_set
    then
        if control == 7  and value == 0 
        then
            search_wifi_clear()
            esp32_search_wifi()
            search_wifi_num = 0
        elseif control == 8  and value == 0 
        then
            cwifi_pwd = get_text(screen_wifi_set,5)
            esp32_connect_ap(cwifi_ssid,cwifi_pwd)
            set_text(screen_wifi_set,1,'连接中')
            set_text(screen_wifi_set,2,'')
            set_text(screen_wifi_set,3,'')
        end
    end
    
    if screen == screen_search_wifi
    then
        if control == 21 and value == 0 
        then
            search_wifi_clear()
            esp32_search_wifi()
            search_wifi_num = 0
        end
        if control > 10 and control <21  and value == 0 
        then
            cwifi_ssid = get_text(screen_search_wifi,control-10)
            
            set_text(screen_wifi_set,4,cwifi_ssid)
            change_screen(screen_wifi_set)
        end
    end
       
    -- if screen == 17
    -- then
        -- if control == 10  and value == 1 
        -- then
            -- esp32_single_tcp_con('TCP','v0.yiketianqi.com',80)
            -- esp32_tcp_mode(1)
            -- esp32_tcp_sendmode()
        -- end
    -- end
    
end

function on_tcp_send_cb(key,value)
    my_esp_log('on_tcp_send_cb key:'..key..',value:'..value)
    if string.find(key, '+CIPSEND') ~= nil and string.find(value,'>')~=nil
    then
        esp32_tcp_send('GET https://v0.yiketianqi.com/api?version=v61&appid=37231943&appsecret=2BJ3teqj&city=%E5%B9%BF%E5%B7%9E HTTP/1.1\r\n')
        esp32_tcp_send('Host: tianqiapi.com\r\n')
        esp32_tcp_send('\r\n')
        enbit_http_getwea = 1
    end
    
end

--[[***************************************************************************
** Function name : on_uart_recv_data
** Descriptions  : 接收串口1的数据的回调函数。串口1是普通串口。
**                 虚拟屏调试时, air_debug_mode = 1，处理串口1的数据。
** @packet       : 接收的数据包
** @return       : nil,无返回值
***************************************************************************--]]
function on_uart_recv_data(packet)
    --wifi模块直接PC串口
    if air_debug_mode == 1 
    then
        on_esp_recv_data(packet)
    end
    if air_debug_mode == 0
    then
        uart_send_data3(packet)
    end
end

--[[***************************************************************************
** Function name:  on_uart_recv_data3
** Descriptions:   接收串口3的数据的回调函数。串口3是连接4G模块。
***************************************************************************--]]
function on_uart_recv_data3(packet)
    on_esp_recv_data(packet)
end




