/* * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2020-05-28 Administrator the first version */ #include #include "hmi.h" #include #include #include "stdarg.h" #include "string.h" #include "stdio.h" #include "dtu_uart2.h" #include #include "control.h" #include "sht30_collect.h" #include #include "sound.h" #include #include "beep.h" #include "test.h" #include "protocol.h" #define DBG_ENABLE #define DBG_COLOR #define DBG_TAG "dtu" #define DBG_LEVEL DBG_LOG #include //must after of DBG_LVL, DBG_TAG or other options #define DTU_THREAD_PRIORITY 6 // 线程优先级 #define DTU_THREAD_STACK_SIZE 2048 + 1024 // 线程栈空间大小 #define DTU_THREAD_TIMESLICE 5 // 时间片 Device_Status_typedef device_status; DataTemp data_arry; JD_Test_Sta jts; extern uint16_t RayTigCnt; void list_mem(void); /* 串口接收消息结构*/ struct rx_msg { rt_device_t dev; rt_size_t size; }; /* 消息队列句柄 */ static struct rt_messagequeue rx_mq_dtu; rt_thread_t dtu_recv_data = RT_NULL; rt_thread_t dtu_send_data = RT_NULL; rt_device_t dtuserial; /*串口设备句柄*/ struct serial_configure dtuconfig = RT_SERIAL_CONFIG_DEFAULT; /*初始化配置参数*/ static uint8_t makejson_sta = 0; #include #include "rs485.h" #define return_modle "{\"cmd\": \"data\", \"ext\": %s}" extern void getEcodeData(uint8_t type); extern wm_Def workmode; extern WorkMode_Def WorkModeList[TypeMAX_wx]; extern Caw_def Check_Allow_Work(void); extern Sensor sensor[MAX_SENSOR_NUM]; extern void CollFanSetPWM(uint8_t percent); extern wm_Def workmode; extern uint8_t ReFlash_RTC(void); extern RTC_DateTypeDef GetDate; extern RTC_TimeTypeDef GetTime; #include "rs485.h" extern Sensor sensor[MAX_SENSOR_NUM]; extern char CamFree; extern char stop_getinfo; extern uint16_t INR_DAT; extern uint16_t INR_PIC; /** * @brief 初始化用于与上层dtu通信的串口 - 串口2 * * @return int 成功返回RT_EOK */ static int DTU_uart2_init(void) { dtuserial = rt_device_find(DTU_UART_NAME); /*修改串口配置参数*/ dtuconfig.baud_rate = BAUD_RATE_115200; // 修改波特率9600 dtuconfig.data_bits = DATA_BITS_8; // 数据位8c dtuconfig.stop_bits = STOP_BITS_1; // 停止位1 dtuconfig.bufsz = 1024; // 缓冲区1k dtuconfig.parity = PARITY_NONE; // 奇校验 /* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */ rt_device_control(dtuserial, RT_DEVICE_CTRL_CONFIG, &dtuconfig); /* step4:打开串口设备。以DMA接收及轮询发送模式打开串口设备 */ rt_device_open(dtuserial, RT_DEVICE_FLAG_DMA_RX); return RT_EOK; } /*数据发送*/ /** * @brief 将组包完成后的json字符串发送到dtu * * @param fmt 字符串模型 * @param ... 可变参数 */ void DTU_Write(char *fmt, ...) { rt_pin_mode(GET_PIN(B, 14), PIN_MODE_OUTPUT); rt_pin_write(GET_PIN(B, 14), 1); stop_getinfo = 1; rt_thread_mdelay(1000); const char dtu_conf[4] = {device_status.vol, 0x00, 0x00, 0x00}; va_list arg; static char dtu_str[800]; rt_size_t str_length; va_start(arg, fmt); str_length = rt_vsnprintf(dtu_str, sizeof(dtu_str) - 1, fmt, arg); if (str_length > 800 - 1) str_length = 800 - 1; // rt_kprintf("DTU_Write data:%d\n%s\n", str_length, dtu_str); rt_device_write(dtuserial, 0, dtu_str, str_length); if (strstr(dtu_str, "volume") != RT_NULL) { rt_device_write(dtuserial, 0, dtu_conf, 4); } else if (strstr(dtu_str, "reset") != RT_NULL) { const char dtu_conf[4] = {7, 0x00, 0x00, 0x00}; rt_device_write(dtuserial, 0, dtu_conf, 4); } va_end(arg); memset(dtu_str, '\0', sizeof(dtu_str)); rt_pin_write(GET_PIN(B, 14), 0); stop_getinfo = 0; } /* 接收数据回调函数 */ static rt_err_t dtu_input(rt_device_t dev, rt_size_t size) { struct rx_msg msg; rt_err_t result; msg.dev = dev; msg.size = size; result = rt_mq_send(&rx_mq_dtu, &msg, sizeof(struct rx_msg)); if (result == -RT_EFULL) { /* 消息队列满 */ rt_kprintf("message queue full! A\n"); } return result; } extern SYSCFG syscfg; /* 入口函数-指令接收*/ /** * @brief dtu数据的接收线程 * * @param parameter NULL */ static void dtu_thread_entry_recv(void *parameter) { struct rx_msg msg; rt_err_t result; rt_uint32_t rx_length; rt_uint32_t rx_err = 0; static char str_check[2] = {'{', '}'}; static char rx_buffer[512]; static char rx_buffer_tmp[512]; static char rx_buffer_tmp2[512]; while (1) { rt_memset(&msg, 0, sizeof(msg)); // 从消息队列中获取被回调函数放入消息队列中的内容 result = rt_mq_recv(&rx_mq_dtu, &msg, sizeof(struct rx_msg), 100); if (result == RT_EOK) { rx_err = 0; rx_length = (sizeof(rx_buffer) - 1) > msg.size ? msg.size : sizeof(rx_buffer) - 1; rx_length = rt_device_read(msg.dev, 0, &rx_buffer[0], rx_length); rx_buffer[rx_length] = '\0'; LOG_D("recv data:>>>%s<<<", rx_buffer); if (strstr(rx_buffer, "{") == RT_NULL || strstr(rx_buffer, "}") == RT_NULL) { HMI_WRITE("sysTest.result.txt=\"%s\"", rx_buffer); } if (strstr(rx_buffer, "图片上传已完成") != RT_NULL) // Function(B) { CamFree = 1; // UpLoad_Data(2); // 拍照完成回复(落虫计数) } if (strstr(rx_buffer, "图片上传开始") != RT_NULL && syscfg.photo_finsh == 1) // Function(B) { syscfg.photo_finsh = 2; // 拍照开始回复 } // 过滤异常数据 char str_check_head[2]; char str_check_end[2]; rt_sprintf(str_check_head, "%c", rx_buffer[0]); rt_sprintf(str_check_end, "%c", rx_buffer[rx_length - 1]); if (str_check_end[0] == str_check[1] && str_check_head[0] == str_check[0]) { parseDtu(rx_buffer); rt_memset(rx_buffer, 0, sizeof(rx_buffer)); rt_memset(rx_buffer_tmp, 0, sizeof(rx_buffer_tmp)); rt_memset(rx_buffer_tmp2, 0, sizeof(rx_buffer_tmp2)); } else { rt_sprintf(rx_buffer_tmp2, "%s", rx_buffer); rt_sprintf(rx_buffer, "%s%s", rx_buffer_tmp, rx_buffer_tmp2); // rt_kprintf("rxbuffer:%s",rx_buffer); parseDtu(rx_buffer); rt_memset(rx_buffer, 0, sizeof(rx_buffer)); rt_memset(rx_buffer_tmp, 0, sizeof(rx_buffer_tmp)); rt_memset(rx_buffer_tmp2, 0, sizeof(rx_buffer_tmp2)); // rt_kprintf("%s",rx_buffer); } } else { rx_err++; if (rx_err == 54000) // 90分钟未接收到数据 { if (device_status.version_type == 6) { LOG_E("RK3399 transter Error!"); ctr_photo(OFF); } else { ctr_RTU_DTU(OFF); } } else if (rx_err == 54100 && device_status.bat_status == 0) { LOG_W("通信中断,RTU重新上电"); rx_err = 0; ctr_RTU_DTU(ON); ctr_photo(ON); } } // rt_kprintf("%s\n",rx_json_buffer); // 将内容写回到串口1 // rt_device_write(dtuserial, 0, &rx_json_buffer[0], rx_length); } } /*入口函数-指令发送*/ /** * @brief dtu数据的发送线程 (定时上报数据) * * @param parameter NULL */ static void dtu_thread_entry_send(void *parameter) { device_status.power_status = 1; device_status.num_updata = 0; rt_thread_delay(10000); static rt_uint16_t wait_i = 0; static rt_uint8_t check_i = 0; static rt_uint8_t power_i = 0; uint16_t log_en_inr = 30; // 打印log的速度 数值越小 打印越频繁 static int16_t log_en_cnt = -1; while (1) { if (atoi(device_status.net) == 0) { // if (device_status.rain_status == 1 || device_status.temp_status == 1) // { // if (check_i == 0) // { // check_i = 1; // device_status.num_updata = 0; // } // } // else // { // check_i = 0; // } if (device_status.num_updata != 0) { device_status.num_updata--; // 屏幕休眠 // if (device_status.num_updata == (device_status.dattim * 60 - 10)) // { // HMI_WRITE("sleep=%d", 1); // } // 检测到电源掉电 if (atoi(device_status.voltage) == 0 && device_status.power_status == 1) { power_i++; // 确定网络状态 if (power_i == 10) { rt_sprintf(device_status.net, "1"); HMI_WRITE("sleep=%d", 1); // 屏幕休眠 DTU_Write("%s", makeJson_Warn("power down", "power")); device_status.power_status = 0; rt_thread_delay(5000); ctr_router(OFF); ctr_RTU_DTU(OFF); power_i = 0; } } if (atoi(device_status.voltage) > 12 && device_status.power_status == 0) // 电压正常 { device_status.power_status = 1; ctr_router(ON); ctr_RTU_DTU(ON); power_i = 0; } } else { // /** // * 250314 低功耗改进 触发工作模式下由这里负责 // */ // if (Check_Allow_Work() == res_ok && workmode == RunTime_Tig_wx) // { // // SendReadInfo(); // rt_thread_mdelay(1000); // UpLoad_Data(0); // rt_kprintf("UpLoad_Data Mark A %d\n\n", device_st atus.num_updata); // } if (atoi(device_status.fuse_voltage) < 1) { rt_thread_delay(500); static char res[30]; sprintf(res, "Fuse is fusing:%s", device_status.fuse_voltage); char *res_fuse_warn = makeJson_Warn(res, "device"); DTU_Write("%s", res_fuse_warn); rt_free(res_fuse_warn); } if (syscfg.dattim == 0) ef_get_env_blob("syscfg", &syscfg, sizeof(syscfg), NULL); if (syscfg.dattim == 0) syscfg.dattim = 20; // 数据上传时间间隔设置为0? if (device_status.bat_status == 0) device_status.power_status = 1; // 解除欠压,清除标志位 device_status.num_updata = (syscfg.dattim * 60); Request_ntp(); rt_kprintf("UpLoad_Data Mark A set finsh %d\n\n", device_status.num_updata); } } // else // 250327 去除了备用电池的逻辑 // { // wait_i++; // if (chk_log_time) // { // LOG_I("wait connect internet......%d", wait_i); // } // // // 检测到电源掉电 // if (atoi(device_status.voltage) == 0 && device_status.power_status == 1 && wait_i > 200) // { // check_i++; // LOG_W("断网状态下检测到设备断电!%d", atoi(device_status.voltage)); // if (check_i == 10) // { // device_status.power_status = 0; // rt_thread_delay(5000); // ctr_router(OFF); // ctr_RTU_DTU(OFF); // check_i = 0; // } // } // if (Read_Real_Voltage() / 100 > 10 && device_status.power_status == 0) // { // check_i = 0; // LOG_I("电源恢复正常,打开路由器和RTU供电!"); // device_status.power_status = 1; // // 打开路由器和RTU供电 // ctr_router(ON); // ctr_RTU_DTU(ON); // } // } rt_thread_mdelay(1000); } } /* 创建线程 */ /** * @brief 用于创建dtu通信相关的线程 * * 该线程在主线程中-读取完保存的设备参数之后调用 * * @return int 完成后返回RT_EOK */ int dtu_data_play(void) { rt_err_t rm_dtu_result; DTU_uart2_init(); // 初始化消息队列 rm_dtu_result = rt_mq_init(&rx_mq_dtu, "dtu", &data_arry.msg_pool[0], 128 - sizeof(void *), sizeof(data_arry.msg_pool), RT_IPC_FLAG_FIFO); if (rm_dtu_result == RT_EOK) { rt_kprintf("消息队列创建成功!!"); } else { rt_kprintf("消息队列创建失败!!"); } /* 设置接收回调函数 */ rt_device_set_rx_indicate(dtuserial, dtu_input); /*创建线程-指令发送*/ dtu_send_data = rt_thread_create("DTU_Uart_thread_send", dtu_thread_entry_send, RT_NULL, DTU_THREAD_STACK_SIZE, 3, // 优先级高是为了保证数据上传的频率的精确度 20 // 时间片 ); /* 创建线程-指令接收解析*/ dtu_recv_data = rt_thread_create("DTU_Uart_thread_recv", dtu_thread_entry_recv, RT_NULL, DTU_THREAD_STACK_SIZE + 1024, DTU_THREAD_PRIORITY, DTU_THREAD_TIMESLICE); /* 如果获得线程控制块,启动这个线程 */ if (dtu_send_data != RT_NULL) rt_thread_startup(dtu_send_data); /* 如果获得线程控制块,启动这个线程 */ if (dtu_recv_data != RT_NULL) rt_thread_startup(dtu_recv_data); return RT_EOK; } //{"cmd": "platform", "ext": {"type": "120.27.222.26"}} /** * @brief 组包平台参数的json * * @param plt 平台参数的内容 * @return char* 组包完成后的字符串指针 */ char *makeJson_platform(char *plt) { cJSON *platform = NULL; platform = cJSON_CreateObject(); if (NULL == platform) { return NULL; } cJSON_AddStringToObject(platform, "cmd", "platform"); cJSON *extstr = NULL; extstr = cJSON_CreateObject(); if (NULL == extstr) { return NULL; } cJSON_AddItemToObject(platform, "ext", extstr); cJSON_AddStringToObject(extstr, "type", plt); char *p_str = cJSON_PrintUnformatted(platform); if (NULL == p_str) { cJSON_Delete(platform); return NULL; } cJSON_Delete(platform); return p_str; } /** * @brief 组包拍照指令的json * * @return char* 完成后的指针 */ char *makeJson_takephoto() { cJSON *takephoto = NULL; takephoto = cJSON_CreateObject(); if (NULL == takephoto) { return NULL; } cJSON_AddStringToObject(takephoto, "cmd", "takephoto"); char *takephoto_str = cJSON_PrintUnformatted(takephoto); if (NULL == takephoto_str) { cJSON_Delete(takephoto); return NULL; } cJSON_Delete(takephoto); return takephoto_str; } /** * @brief 组包RTU拍照的json * * @return char* 完成后的指针 */ char *makeJson_Rtutakephoto() { cJSON *tJsonRoot = NULL; tJsonRoot = cJSON_CreateObject(); if (NULL == tJsonRoot) { return NULL; } cJSON_AddStringToObject(tJsonRoot, "cmd", "ctrl"); cJSON *tpubstring = NULL; tpubstring = cJSON_CreateObject(); if (NULL == tpubstring) { LOG_E("cJSON tpubstring NULL!!!\n"); return NULL; } cJSON_AddItemToObject(tJsonRoot, "ext", tpubstring); cJSON_AddStringToObject(tpubstring, "takephoto", "2"); char *t = cJSON_PrintUnformatted(tJsonRoot); if (NULL == t) { cJSON_Delete(tJsonRoot); return NULL; } cJSON_Delete(tJsonRoot); return t; } // 预警消息 /** * @brief 组包预警信息的json * * @param s status * @param t type * @return char* 完成后的指针 */ char *makeJson_Warn(char *s, char *t) { cJSON *wJsonRoot = NULL; wJsonRoot = cJSON_CreateObject(); if (NULL == wJsonRoot) { return NULL; } cJSON_AddStringToObject(wJsonRoot, "cmd", "warn"); cJSON *pubstring = NULL; pubstring = cJSON_CreateObject(); if (NULL == pubstring) { rt_kprintf("cJSON pubstring NULL!!!\n"); return NULL; } cJSON_AddItemToObject(wJsonRoot, "ext", pubstring); cJSON_AddStringToObject(pubstring, "status", s); // cJSON_AddStringToObject(pubstring, "type", t); char *w = cJSON_PrintUnformatted(wJsonRoot); if (NULL == w) { cJSON_Delete(wJsonRoot); rt_kprintf("wJsonRoot cJSON_Delete NULL!!!\n"); return NULL; } cJSON_Delete(wJsonRoot); return w; } #include extern Limit limit; extern SYSCFG syscfg; extern wm_Def workmode; /*生成JSON数据*/ /** * @brief 组包设备状态信息的json * * @return char* 完成后的指针 */ char *makeJson(uint8_t type) { char utos[5]; if (device_status.gps == NULL) rt_sprintf(device_status.gps, "0"); // 如果设备工作并且电流小于500,并且不是上电启动灯管异常 if (atoi(device_status.power) < 400 && atoi(device_status.power) != 0 && device_status.work_status == 1 && makejson_sta != 0) { #if LAMP_EN == 0 LOG_I("Current is:%d", atoi(device_status.power)); if (atoi(device_status.power) > 10) // 过滤电流检测芯片损坏导致电流直为0 的异常 device_status.lamp_status = 1; #endif } else { device_status.lamp_status = 0; } if (atoi(device_status.power) > 5000) rt_sprintf(device_status.power, "0.01"); makejson_sta = 1; time_t stamp = time(RT_NULL); static struct tm tm; gmtime_r(&stamp, &tm); rt_sprintf(device_status.stamp, "%04d%02d%02d%02d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); cJSON *pJsonRoot = NULL; pJsonRoot = cJSON_CreateObject(); if (NULL == pJsonRoot) { rt_kprintf("cJSON pJsonRoot NULL!!!\n"); return NULL; } if (strstr(device_status.project, "A7_DTU_V3") != RT_NULL) { cJSON_AddStringToObject(pJsonRoot, "cmd", "read_data"); } else { cJSON_AddStringToObject(pJsonRoot, "cmd", "data"); } cJSON *pSubJson = NULL; pSubJson = cJSON_CreateObject(); if (NULL == pSubJson) { rt_kprintf("cJSON pSubJson NULL!!!\n"); return NULL; } memset(device_status.driver, 0, sizeof(device_status.driver)); rt_sprintf(device_status.driver, "%s-%s", VERSION_NUM, device_status.driver_4g); if (device_status.sensor_485_sta != 0) { if (strstr(device_status.driver, "485") == RT_NULL) strcat(device_status.driver, ".485"); } cJSON_AddItemToObject(pJsonRoot, "ext", pSubJson); cJSON_AddStringToObject(pSubJson, "dver", device_status.driver); // 版本号,字符型 cJSON_AddStringToObject(pSubJson, "proj", device_status.project); // 项目类型 // 设备类型 rt_sprintf(utos, "%d", device_status.dtype); cJSON_AddStringToObject(pSubJson, "dtype", utos); // 光控定时时长 rt_sprintf(utos, "%d", limit.LuxTime); cJSON_AddStringToObject(pSubJson, "tt", utos); // 时控定时开始 rt_sprintf(utos, "%d", device_status.collecting_sh1); cJSON_AddStringToObject(pSubJson, "collstart", utos); // 时控定时结束 rt_sprintf(utos, "%d", device_status.collecting_eh1); cJSON_AddStringToObject(pSubJson, "collend", utos); // 定时模式 rt_sprintf(utos, "%d", workmode); cJSON_AddStringToObject(pSubJson, "ts", utos); // 温控开关 rt_sprintf(utos, "%d", limit.temhumEN); cJSON_AddStringToObject(pSubJson, "tps", utos); // 高温保护 rt_sprintf(utos, "%d", limit.temp_up); cJSON_AddStringToObject(pSubJson, "tph", utos); // 低温保护 rt_sprintf(utos, "%d", limit.temp_dw); cJSON_AddStringToObject(pSubJson, "tpl", utos); // 雨控开关 rt_sprintf(utos, "%d", limit.RainEN); cJSON_AddStringToObject(pSubJson, "rps", utos); // 当前光控状态 rt_sprintf(utos, "%d", device_status.sun_status); cJSON_AddStringToObject(pSubJson, "lps", utos); // 当前雨控状态 rt_sprintf(utos, "%d", device_status.rain_status); cJSON_AddStringToObject(pSubJson, "nrps", utos); // 当前温控状态 rt_sprintf(utos, "%d", device_status.rain_status); cJSON_AddStringToObject(pSubJson, "ntps", utos); // 电池状态 rt_sprintf(utos, "%d", device_status.bat_status); cJSON_AddStringToObject(pSubJson, "batStatus", utos); // // 灯管状态 // rt_sprintf(utos, "%d", rt_pin_read(LAMP_SW)); // cJSON_AddStringToObject(pSubJson, "lamp", utos); // 补光灯 rt_sprintf(utos, "%d", rt_pin_read(LED_SW)); cJSON_AddStringToObject(pSubJson, "led", utos); // 定位状态 cJSON_AddStringToObject(pSubJson, "gps", device_status.gps); // 开关状态 rt_sprintf(utos, "%d", device_status.ds); cJSON_AddStringToObject(pSubJson, "ds", utos); char *temp_c = NULL; char *humi_c = NULL; if (sensor[s_Temp].online && strstr(sensor[s_Temp].eValue, "99.99" == NULL)) { temp_c = sensor[s_Temp].eValue; } else { temp_c = device_status.tempture; } if (sensor[s_Humi].online && strstr(sensor[s_Humi].eValue, "99.99" == NULL)) { humi_c = sensor[s_Humi].eValue; } else { humi_c = device_status.humidity; } // rt_kprintf("temp %s humi %s\n",temp_c , humi_c); // 温度 cJSON_AddStringToObject(pSubJson, "at", temp_c); // 湿度 cJSON_AddStringToObject(pSubJson, "ah", humi_c); cJSON_AddStringToObject(pSubJson, "imei", device_status.imei); // IMEI cJSON_AddStringToObject(pSubJson, "iccid", device_status.iccid); // ICCID cJSON_AddStringToObject(pSubJson, "stamp", device_status.stamp); // 时间 // 经度 cJSON_AddStringToObject(pSubJson, "lng", device_status.lng); // 纬度 cJSON_AddStringToObject(pSubJson, "lat", device_status.lat); // 是否为上电开机 cJSON_AddNumberToObject(pSubJson, "rcnt", device_status.rebootcnt); // 电流(当前) cJSON_AddStringToObject(pSubJson, "current", device_status.power); // 电压 cJSON_AddStringToObject(pSubJson, "vbat", device_status.voltage); // 数据上传间隔 rt_sprintf(utos, "%d", syscfg.dattim); cJSON_AddStringToObject(pSubJson, "dat_f", utos); // 照片上传间隔 rt_sprintf(utos, "%d", syscfg.photim); cJSON_AddStringToObject(pSubJson, "pho_f", utos); // 风机调速 rt_sprintf(utos, "%d", RayTigCnt); cJSON_AddStringToObject(pSubJson, "RayTigCnt", utos); // 信号强度 cJSON_AddStringToObject(pSubJson, "csq", device_status.csq); char *p = cJSON_PrintUnformatted(pJsonRoot); if (NULL == p) { cJSON_Delete(pJsonRoot); rt_kprintf("cJSON_Delete NULL!!!\n"); return NULL; } cJSON_Delete(pJsonRoot); return p; } /** * @brief 组包返回信息的json * * @return char* 组包完成后的字符串指针 */ char *makeJson_Return(char *cmd, char *data) { // 创建一个JSON对象 cJSON *root = cJSON_CreateObject(); if (root == NULL) { fprintf(stderr, "Error creating JSON object\n"); return NULL; } // 在JSON对象中添加键值对 cJSON_AddStringToObject(root, cmd, data); // 将JSON对象转换为字符串 char *json_str = cJSON_Print(root); if (json_str == NULL) { fprintf(stderr, "Error printing JSON string\n"); // 释放JSON对象的内存 cJSON_Delete(root); return NULL; } // 释放JSON对象的内存 cJSON_Delete(root); return json_str; } /***************** 241217 新增控制指令框架 *******************/ static RC_Def rcdList[TypeMAX_rcd] = { {read_limit_rcd, "read_limit"}, {TEMP_ON_rcd, "TEMP_ON"}, {TEMP_OFF_rcd, "TEMP_OFF"}, {RAIN_ON_rcd, "RAIN_ON"}, {RAIN_OFF_rcd, "RAIN_OFF"}, {RunLight_rcd, "RunLight"}, {RunTime_rcd, "RunTime"}, {Read_ecode_rcd, "Read_ecode"}, {FBtest_rcd, "FB_TEST"}, {SCMtest_rcd, "SCM_TEST"}, {Clear_log_rcd, "clear_log"}, {Read_status_rcd, "Read_status"}}; static RCD Get_RCType(char *cmd) { RCD res = TypeMAX_rcd; for (uint8_t a = 0; a < TypeMAX_rcd; a++) { if (strstr(cmd, rcdList[a].keyword) != NULL) { return rcdList[a].rcd; } } return res; } static char RC_Res[512] = {0}; extern Reflash_test_sta rts; /** * @brief 把收到的请求指令解析出来 * * @param cmd 指令 */ void prase_Rcmd(char *cmd) { if (strstr(cmd, "RC") == NULL || Get_RCType(cmd) == TypeMAX_rcd) { rt_kprintf("prase_Rcmd no keyword find \n\n"); return; } RCD type = Get_RCType(cmd); // rt_kprintf("type %d \n", type); switch (type) { case read_limit_rcd: sprintf(RC_Res, "\"温湿控- %s | 光控-%s | 雨控-%s\"", limit.temhumEN ? "开" : "关", limit.LuxEN ? "开" : "关", limit.RainEN ? "开" : "关"); break; case TEMP_ON_rcd: limit.temhumEN = ON; ef_set_env_blob("limit", &limit, sizeof(Limit)); sprintf(RC_Res, "\"%s\"", rcdList[type].keyword); break; case TEMP_OFF_rcd: limit.temhumEN = OFF; ef_set_env_blob("limit", &limit, sizeof(Limit)); sprintf(RC_Res, "\"%s\"", rcdList[type].keyword); break; case RAIN_ON_rcd: limit.RainEN = ON; ef_set_env_blob("limit", &limit, sizeof(Limit)); sprintf(RC_Res, "\"%s\"", rcdList[type].keyword); break; case RAIN_OFF_rcd: limit.RainEN = OFF; ef_set_env_blob("limit", &limit, sizeof(Limit)); sprintf(RC_Res, "\"%s\"", rcdList[type].keyword); break; case RunLight_rcd: limit.LuxEN = ON; if (limit.LuxTime == 0) { limit.LuxTime = gktime_def; } ef_set_env_blob("limit", &limit, sizeof(Limit)); sprintf(RC_Res, "\"%s\"", rcdList[type].keyword); break; case RunTime_rcd: limit.LuxEN = OFF; ef_set_env_blob("limit", &limit, sizeof(Limit)); sprintf(RC_Res, "\"%s\"", rcdList[type].keyword); break; case Read_ecode_rcd: getEcodeData(1); break; case Read_status_rcd: status_Pri(0); break; case FBtest_rcd: jts.FBtest = ON; status_Pri(2); break; case SCMtest_rcd: jts.scm_test = ON; status_Pri(3); break; case Clear_log_rcd: ef_log_clean(); char static_array[] = "{\"cmd\":\"data\",\"ext\":{\"RC\":\"Ecode 已清空\"}}"; DTU_Write(static_array); break; default: break; } if (type != Read_ecode_rcd) { // rt_kprintf("\n"); // rt_kprintf(return_modle, RC_Res); // rt_kprintf("\n"); DTU_Write(return_modle, RC_Res); } } /***************** 241217 新增控制指令框架 *******************/ /** * @brief 获取Cjson数值 * * @return int */ int cjson_getval(cJSON *json) { if (json->type == cJSON_Number) { return json->valueint; } else if (json->type == cJSON_String) { return atoi(json->valuestring); } else { return -99; } } // #include "Work_TN.h" struct tm time_c = {0}; // 缓存 同时用于返回时间 /** * @brief 检查将要对时的时间是否合法 * * @param cmd 字符串的时间 * @return NULL-非法 other-合法 */ static struct tm *CHECK_DATE(char *cmd) { if (cmd == NULL) { return NULL; } ReFlash_RTC(); #define TIME_STEP 10 // 时间差值在30分钟内的 可以直接对时 char datetime[16] = {0}; strncpy(datetime, cmd, 16); // uint32_t ntc_time = atoi(datetime); uint32_t yyyy = 2000 + GetDate.Year; uint32_t mm = GetDate.Month; uint32_t dd = GetDate.Date; uint32_t hh = GetTime.Hours; uint32_t min = GetTime.Minutes; // uint32_t now_time = (yyyy * 1000000) + (mm * 10000) + (dd * 100) + hh; int32_t diff_val = 0; static char year_s[5], month_s[3], day_s[3], hour_s[3], min_s[3], sec_s[3]; strncpy(year_s, datetime, 4); strncpy(month_s, datetime + 4, 2); strncpy(day_s, datetime + 6, 2); strncpy(hour_s, datetime + 8, 2); strncpy(min_s, datetime + 10, 2); strncpy(sec_s, datetime + 12, 2); if (strlen(cmd) != 14) { return NULL; } if (yyyy < 2024) { goto _USE_NTP; } if (atoi(year_s) == yyyy && atoi(month_s) == mm && atoi(day_s) == dd) // 年月日相同 { diff_val = (atoi(hour_s) * 60 + atoi(min_s)) - (hh * 60 + min); if (abs(diff_val) > TIME_STEP) { if (diff_val > 0) { goto _TRUN_RIGHT; } else { goto _TRUN_LIFT; } } else { goto _USE_NTP; } } else // 年月日不同 { if (atoi(year_s) > yyyy) { goto _TRUN_RIGHT; } if (atoi(year_s) < yyyy) { goto _TRUN_LIFT; } if (atoi(month_s) > mm) { goto _TRUN_RIGHT; } if (atoi(month_s) < mm) { goto _TRUN_LIFT; } if (atoi(day_s) > dd) { goto _TRUN_RIGHT; } if (atoi(day_s) < dd) { goto _TRUN_LIFT; } } _USE_NTP: // LOG_I("CHECK_DATE OUT A %s\n" , cmd); time_c.tm_year = atoi(year_s); time_c.tm_mon = atoi(month_s); time_c.tm_mday = atoi(day_s); time_c.tm_hour = atoi(hour_s); time_c.tm_min = atoi(min_s); time_c.tm_sec = atoi(sec_s); LOG_I("A : %02d-%02d-%02d %02d:%02d:%02d", time_c.tm_year, time_c.tm_mon, time_c.tm_mday, time_c.tm_hour, time_c.tm_min, time_c.tm_sec); return &time_c; _TRUN_LIFT: // 向后对时(当前时间过快) if ((min + (hh * 60) - TIME_STEP) > 0) { time_c.tm_year = GetDate.Year + 2000; time_c.tm_mon = GetDate.Month; time_c.tm_mday = GetDate.Date; time_c.tm_hour = (min + (hh * 60) - TIME_STEP) / 60; time_c.tm_min = (min + (hh * 60) - TIME_STEP) % 60; // LOG_E("CHECK_DATE OUT B %s\n" , cmd); LOG_I("B : %02d-%02d-%02d %02d:%02d:%02d", time_c.tm_year, time_c.tm_mon, time_c.tm_mday, time_c.tm_hour, time_c.tm_min, time_c.tm_sec); return &time_c; } else { return NULL; } return &time_c; _TRUN_RIGHT: // 向前对时(当前时间过慢) if ((min + (hh * 60) + TIME_STEP) < 1440) { time_c.tm_year = GetDate.Year + 2000; time_c.tm_mon = GetDate.Month; time_c.tm_mday = GetDate.Date; time_c.tm_hour = (min + (hh * 60) + TIME_STEP) / 60; time_c.tm_min = (min + (hh * 60) + TIME_STEP) % 60; // LOG_E("CHECK_DATE OUT C %s\n" , cmd); LOG_I("C : %02d-%02d-%02d %02d:%02d:%02d", time_c.tm_year, time_c.tm_mon, time_c.tm_mday, time_c.tm_hour, time_c.tm_min, time_c.tm_sec); return &time_c; } else { return NULL; } return &time_c; } extern holdon_rtcreflash; /** * @brief 设置NTP时间 * * @param ntptime */ void EXE_NTP_SETTIME(struct tm *ntptime) { if (ntptime == NULL) { return; } static char err_cnt = 0; if (ntptime->tm_year >= 2022 && ntptime->tm_year < 3000 && ntptime->tm_mon > 0 && ntptime->tm_mon < 13 && ntptime->tm_mday > 0 && ntptime->tm_mday < 32) { if (atoi(device_status.net) == 0 && ntptime->tm_year >= 2022) { holdon_rtcreflash = 1; rt_thread_mdelay(300); if (set_date(ntptime->tm_year, ntptime->tm_mon, ntptime->tm_mday) == RT_EOK) { LOG_I("设置日期:%d年%d月%d日", ntptime->tm_year, ntptime->tm_mon, ntptime->tm_mday); if (ntptime->tm_hour > 0 && ntptime->tm_hour <= 24 && ntptime->tm_min >= 0 && ntptime->tm_min <= 60 && ntptime->tm_sec >= 0 && ntptime->tm_sec <= 60) { LOG_I("设置时间:%d时%d分%d秒", ntptime->tm_hour, ntptime->tm_min, ntptime->tm_sec); set_time(ntptime->tm_hour, ntptime->tm_min, ntptime->tm_sec); rt_thread_mdelay(1500); if (GetDate.Year > 200) { err_cnt++; LOG_W("set_time failed . %d", err_cnt); if (err_cnt > 9) { Recode_e_code(e_rtc_fail, GetDate.Year, "RTC时间写入失败"); rt_hw_cpu_reset(); } } else if (err_cnt > 0) { err_cnt--; } } else { rt_kprintf("else B %d:%d:%d\n", ntptime->tm_hour, ntptime->tm_min, ntptime->tm_sec); } } else { LOG_E("set_date failed!"); rt_hw_rtc_init(); } } else { LOG_E("网络连接失败,同步时间失败!"); } } holdon_rtcreflash = 0; } extern Reflash_test_sta rts; extern void Get_work_mode(void); extern char errcnt_getinfo; volatile char Demo_Mode_NEW = 0; // JSON数据解析 /** * @brief 解析dtu发来的指令 * * @param json_string 收到的json字符串 * @return int 0 完成 */ int parseDtu(char *json_string) { extern int rt_hw_rtc_init(void); char *json_s = NULL; cJSON *item_cmd = NULL; // 嵌套ext cJSON *item_ext = NULL; // 嵌套ext cJSON *item_checkself = NULL; // /** * 有用的小虫体指令 * */ cJSON *collstart = NULL; // 时控开始(整型 / 时) cJSON *collend = NULL; // 时控结束(整型 / 时) cJSON *tt = NULL; // 光控定时时长(整型 / 时) cJSON *ts = NULL; // 工作模式(整型 / 0-时控 1-光控) cJSON *tpl = NULL; // 低温保护阈值 cJSON *tph = NULL; // 高温保护阈值 cJSON *inr_data = NULL; // 数据上传间隔(整型 / min) cJSON *inr_photo = NULL; // 拍照间隔(整型 / min) cJSON *limit_temp = NULL; // 设置温控开关(bool / 0-关闭 1-开启) cJSON *limit_rain = NULL; // 设置雨控开关(bool / 0-关闭 1-开启) cJSON *Demo_mode = NULL; cJSON *ntp_time = NULL; cJSON *tem = NULL; cJSON *hum = NULL; cJSON *CONTROL = NULL; cJSON *JD_Clear = NULL; /** * 有用的小虫体指令 * */ cJSON *gps = NULL; // 定位状态 cJSON *datetime = NULL; cJSON *lat = NULL; cJSON *lng = NULL; cJSON *csq = NULL; cJSON *net = NULL; cJSON *iccid = NULL; cJSON *imei = NULL; cJSON *sim = NULL; cJSON *volume = NULL; cJSON *driver_4g = NULL; // 版本号 cJSON *project = NULL; // Project cJSON *ds = NULL; // 设备状态 // cJSON *vt = NULL; // 版本类型 // cJSON* account_status = NULL; //卡状态 // cJSON* data_plan = NULL; //套餐 // cJSON* data_usage = NULL; //已使用 // cJSON* expiry_date = NULL; //到期时间 cJSON *mqttcfg1 = NULL; cJSON *mqttcfg2 = NULL; cJSON *type = NULL; cJSON *tmp = NULL; cJSON *link_sta = NULL; cJSON *value_commn = NULL; cJSON *fan_speed = NULL; if (strlen(json_string) < 5) { return; } // rt_kprintf("parseDtu : %s\n", json_string); const char *error_ptr = NULL; cJSON *root = cJSON_ParseWithOpts(json_string, &error_ptr, 1); if (!root) { rt_kprintf("Parse error: ->%s<-\n", error_ptr); return -1; } else if (strstr(json_string, "RC") != NULL) // 私有测试指令 { prase_Rcmd(json_string); cJSON_Delete(root); } else if (strstr(json_string, "DEVICE_SERIAL_NUMBER") != NULL) // 解析新协议指令 { prase_NewCmd(json_string); cJSON_Delete(root); } else { item_cmd = cJSON_GetObjectItem(root, "cmd"); item_ext = cJSON_GetObjectItem(root, "ext"); item_checkself = cJSON_GetObjectItem(root, "selfcheck"); // item_data = cJSON_GetObjectItem(root,"data"); if (item_checkself != NULL) { // 自检签名 LOG_I("自检签名:%s", item_checkself->valuestring); // 执行一键测试任务 jts.autotest = ON; device_status.test_flag = 10; } if (item_cmd != RT_NULL) { if (strstr(item_cmd->valuestring, "takephoto") != RT_NULL) { rts.takephoto_t = ON; rt_kprintf("拍照测试:打开\n"); char *photo = makeJson_Warn("takephoto", "control"); DTU_Write("%s", photo); rt_free(photo); } else if (strstr(item_cmd->valuestring, "json_w_clock") != RT_NULL) { rt_kprintf("查询时间配置!\n"); json_s = makeJson_Warn(device_status.json_w_clock, "主动查询"); DTU_Write("%s", json_s); rt_free(json_s); rt_thread_delay(1000); } else if (strstr(item_cmd->valuestring, "json_w_reset") != RT_NULL) { rt_kprintf("查询重置配置!\n"); json_s = makeJson_Warn(device_status.json_w_reset, "主动查询"); DTU_Write("%s", json_s); rt_free(json_s); rt_thread_delay(1000); } else if (strstr(item_cmd->valuestring, "json_w_platform") != RT_NULL) { rt_kprintf("查询平台配置!\n"); json_s = makeJson_Warn(device_status.json_w_platform, "主动查询"); DTU_Write("%s", json_s); rt_free(json_s); rt_thread_delay(1000); } else if (strstr(item_cmd->valuestring, "shake") != RT_NULL) { ctr_shake(ON, 30); char *shake = makeJson_Warn("shake", "control"); DTU_Write("%s", shake); rt_free(shake); rt_thread_delay(2000); } // 远程给rtu重新上电 else if (strstr(item_cmd->valuestring, "ctrl") != RT_NULL) { type = cJSON_GetObjectItem(item_ext, "type"); if (strstr(type->valuestring, "rtu_off_on") != RT_NULL) { LOG_W("DTU 12V Power down"); ctr_RTU_DTU(OFF); rt_thread_delay(5000); ctr_RTU_DTU(ON); } // 对焦拍照 else if (strstr(type->valuestring, "auto_takephoto") != RT_NULL) { device_status.autotakepic = 1; rt_thread_delay(2000); char *auto_takephoto = makeJson_Warn("send cmd success:auto_takephoto", "control"); DTU_Write("%s", auto_takephoto); rt_free(auto_takephoto); } else if (strstr(type->valuestring, "takephoto") != RT_NULL) { rts.takephoto_t = ON; rt_kprintf("拍照测试:打开\n"); } else if (strstr(type->valuestring, "led_on") != RT_NULL) { rts.switchled_t = ON; rt_kprintf("补光测试:打开\n"); } else if (strstr(type->valuestring, "led_off") != RT_NULL) { rts.switchled_t = OFF; rt_kprintf("补光测试:关闭\n"); } else if (strstr(type->valuestring, "FB_TEST") != RT_NULL) { rts.fb_test_t = ON; rt_kprintf("卷带测试:开启\n"); } } // 切换平台 else if (strstr(item_cmd->valuestring, "platform") != RT_NULL) { type = cJSON_GetObjectItem(item_ext, "type"); if (strstr(type->valuestring, "8.136.98.49") != RT_NULL) { rt_sprintf(device_status.mqttcfg1, "8.136.98.49"); ef_set_env_blob("platform", &device_status.mqttcfg1, sizeof(device_status.mqttcfg1)); // 给RTU发送切换指令 DTU_Write("%s", makeJson_platform("8.136.98.49")); rt_free(makeJson_platform("8.136.98.49")); rt_thread_delay(1000); rt_sprintf(device_status.json_w_platform, "平台操作:切换平台>大数据,操作时间:%s", device_status.stamp); json_s = makeJson_Warn(device_status.json_w_platform, "切换平台"); ef_set_env_blob("json_w_platform", &device_status.json_w_platform, sizeof(device_status.json_w_platform)); // 将修改屏幕参数操作记录保存到Flash中 if (atoi(device_status.net) == 0) DTU_Write("%s", json_s); rt_free(json_s); rt_thread_delay(1000); MA_save(); } else if (strstr(type->valuestring, "120.27.222.26") != RT_NULL) { rt_sprintf(device_status.mqttcfg1, "120.27.222.26"); ef_set_env_blob("platform", &device_status.mqttcfg1, sizeof(device_status.mqttcfg1)); // 给RTU发送切换指令 DTU_Write("%s", makeJson_platform("120.27.222.26")); rt_free(makeJson_platform("120.27.222.26")); rt_thread_delay(1000); rt_sprintf(device_status.json_w_platform, "平台操作:切换平台>四情,操作时间:%s", device_status.stamp); json_s = makeJson_Warn(device_status.json_w_platform, "切换平台"); ef_set_env_blob("json_w_platform", &device_status.json_w_platform, sizeof(device_status.json_w_platform)); // 将修改屏幕参数操作记录保存到Flash中 if (atoi(device_status.net) == 0) DTU_Write("%s", json_s); rt_free(json_s); rt_thread_delay(1000); MA_save(); } } // 水稻2000万像素的串口拍照指令 else if (strstr(item_cmd->valuestring, "mvs_photo") != RT_NULL) { HK_TakePhoto(); char *photo = makeJson_Warn("mvs_takephoto", "control"); DTU_Write("%s", photo); rt_free(photo); rt_thread_delay(2000); } else if (strstr(item_cmd->valuestring, "reboot") != RT_NULL) { char *restart = makeJson_Warn("sysrem will restart", "control"); rt_kprintf("%s\n", restart); rt_thread_delay(2000); DTU_Write("%s", restart); rt_hw_cpu_reset(); } else if (strstr(item_cmd->valuestring, "reset") != RT_NULL) { ResetParamDefault(); char *restart = makeJson_Warn("sysrem will reset", "control"); DTU_Write("%s", restart); rt_free(restart); rt_thread_delay(2000); } else if (strstr(item_cmd->valuestring, "update") != RT_NULL) { rt_kprintf("准备升级!!!"); device_status.update_flag = 1; ef_set_env_blob("update_flag", &device_status.update_flag, sizeof(device_status.update_flag)); rt_kprintf("%s\n", makeJson_Warn("system will update", "control")); rt_thread_delay(2000); DTU_Write("%s", makeJson_Warn("system will update", "control")); rt_thread_delay(20); rt_hw_cpu_reset(); } else if (strstr(item_cmd->valuestring, "read") != RT_NULL) { SendReadInfo('A'); device_status.hmi_fresh = 2; device_status.refresh_num = 15; } else if (strstr(item_cmd->valuestring, "poweron") != RT_NULL) { device_status.ds = 1; ef_set_env_blob("ds", &device_status.ds, sizeof(device_status.ds)); // UpLoad_Data(0); // 开启设备开关回复 rt_kprintf("UpLoad_Data Mark B \n\n"); } else if (strstr(item_cmd->valuestring, "poweroff") != RT_NULL) { device_status.ds = 0; ef_set_env_blob("ds", &device_status.ds, sizeof(device_status.ds)); // UpLoad_Data(0); // 关闭设备开关回复 rt_kprintf("UpLoad_Data Mark C \n\n"); } // else if (strstr(item_cmd->valuestring,"log")!=RT_NULL) { // rt_thread_mdelay(2000); // //read_all_flash_log(); // } // 设置温湿度 else if (strstr(item_cmd->valuestring, "sensor") != RT_NULL) { // 2022-04-12add:485传感器正常,不再解析服务器下发的温湿度数据 // if(device_status.sensor_485_sta!=0) return 0; hum = cJSON_GetObjectItem(item_ext, "new_hum"); tmp = cJSON_GetObjectItem(item_ext, "new_tem"); if (hum != NULL && tmp != NULL) { // 先判断是否是空字符再判断数值是否合理 if (strcmp(hum->valuestring, "") != 0 && atoi(hum->valuestring) >= 0 && atoi(hum->valuestring) <= 100 && atoi(hum->valuestring) != 30 && device_status.sensor_485_sta == 0) { if (atoi(hum->valuestring) != atoi(device_status.humidity)) { rt_sprintf(device_status.humidity, "%s", hum->valuestring); ef_set_env_blob("env_h", &device_status.humidity, sizeof(device_status.humidity)); // 湿度 rt_kprintf("保存湿度成功:%d\n", atoi(device_status.humidity)); } rt_kprintf("设置湿度成功:%d\n", atoi(device_status.humidity)); } else { rt_kprintf("设置湿度失败:%s!!!\n", hum->valuestring); } // 先判断是否是空字符再判断数值是否合理 if (strcmp(tmp->valuestring, "") != 0 && atoi(tmp->valuestring) > -50 && atoi(tmp->valuestring) <= 100 && device_status.sensor_485_sta == 0) { if (atoi(tmp->valuestring) != atoi(device_status.tempture)) { rt_sprintf(device_status.tempture, "%s", tmp->valuestring); ef_set_env_blob("env_t", &device_status.tempture, sizeof(device_status.tempture)); // 湿度 rt_kprintf("保存温度成功:%d\n", atoi(device_status.tempture)); } rt_kprintf("设置温度成功:%d\n", atoi(device_status.tempture)); } else { rt_kprintf("设置温度失败:%s!!!\n", tmp->valuestring); } } } else if (strstr(item_cmd->valuestring, "color") != RT_NULL) { if (item_ext != RT_NULL && strstr(item_ext->valuestring, "turn") != RT_NULL) { device_status.run_sta = 5; } else { LOG_W("Unknow cmd value!"); } } else if (strstr(item_cmd->valuestring, "synchronization") != RT_NULL) { errcnt_getinfo = 0; // 收到rtu消息了 #if Color_EN == 0 if (device_status.dtype == 7) { DTU_Write("%s", VERSION_KEY); } else if (device_status.dtype == 3) { DTU_Write("%s", VERSION_KEY); } #endif device_status.refresh_timeout = 0; // driver_4g = cJSON_GetObjectItem(item_ext,"version"); driver_4g = cJSON_GetObjectItem(item_ext, "dver"); // project = cJSON_GetObjectItem(item_ext,"project"); project = cJSON_GetObjectItem(item_ext, "proj"); datetime = cJSON_GetObjectItem(item_ext, "datetime"); lat = cJSON_GetObjectItem(item_ext, "lat"); lng = cJSON_GetObjectItem(item_ext, "lng"); csq = cJSON_GetObjectItem(item_ext, "csq"); net = cJSON_GetObjectItem(item_ext, "net"); sim = cJSON_GetObjectItem(item_ext, "sim"); iccid = cJSON_GetObjectItem(item_ext, "iccid"); imei = cJSON_GetObjectItem(item_ext, "imei"); gps = cJSON_GetObjectItem(item_ext, "gps"); volume = cJSON_GetObjectItem(item_ext, "volume"); mqttcfg1 = cJSON_GetObjectItem(item_ext, "mqttcfg1"); mqttcfg2 = cJSON_GetObjectItem(item_ext, "mqttcfg2"); link_sta = cJSON_GetObjectItem(item_ext, "link_sta"); cJSON *gps_inuse = cJSON_GetObjectItem(item_ext, "gps_inuse"); cJSON *gps_view = cJSON_GetObjectItem(item_ext, "gps_view"); // 如果DTU的IMEI和FLash中的不一样,保存到FLASH value_commn = cJSON_GetObjectItem(item_ext, "photo_sta"); if (value_commn != RT_NULL) { device_status.camsta = value_commn->valueint; if (device_status.camsta == 0) { rt_kprintf("相机已连接 \n"); HMI_WRITE("menu.va_cam.val=1"); } else { rt_kprintf("相机未连接 \n"); HMI_WRITE("menu.va_cam.val=0"); } } value_commn = cJSON_GetObjectItem(item_ext, "cpu_tmp"); if (value_commn != RT_NULL) { HMI_WRITE("menu.cpu_temp.txt=\"%d.%d℃\"", atoi(value_commn->valuestring) / 1000, atoi(value_commn->valuestring) % 1000); } if (strstr(device_status.imei, imei->valuestring) == RT_NULL) { rt_kprintf("Change IMEI:new:%s-old:%s", imei->valuestring, device_status.imei); rt_sprintf(device_status.imei, "%s", imei->valuestring); ef_set_env_blob("imei", &device_status.imei, sizeof(device_status.imei)); // IMEI } else { rt_sprintf(device_status.imei, "%s", imei->valuestring); rt_kprintf("IMEI not change:%s-%s", imei->valuestring, device_status.imei); } // 如果DTU的ICCID和FLash中的不一样,保存到FLASH if (strstr(device_status.iccid, iccid->valuestring) == RT_NULL) { rt_kprintf("Change ICCID:new:%s-old:%s", iccid->valuestring, device_status.iccid); rt_sprintf(device_status.iccid, "%s", iccid->valuestring); ef_set_env_blob("iccid", &device_status.iccid, sizeof(device_status.iccid)); // Iccid } else { rt_sprintf(device_status.iccid, "%s", iccid->valuestring); rt_kprintf("ICCID not change:%s-%s", iccid->valuestring, device_status.iccid); } LOG_I("DTU时间:%s", datetime->valuestring); static char year_s[5], month_s[3], day_s[3], hour_s[3], min_s[3], sec_s[3]; static char Fail_time_cnt = 0; // 计数 strncpy(year_s, datetime->valuestring, 4); strncpy(month_s, datetime->valuestring + 4, 2); strncpy(day_s, datetime->valuestring + 6, 2); strncpy(hour_s, datetime->valuestring + 8, 2); strncpy(min_s, datetime->valuestring + 10, 2); strncpy(sec_s, datetime->valuestring + 12, 2); struct tm *ntptime = CHECK_DATE(datetime->valuestring); if (atoi(year_s) >= 2025 && GetDate.Year < 25) // 250701 修正此处作为保底时间 { Fail_time_cnt++; if (Fail_time_cnt > 10) { EXE_NTP_SETTIME(ntptime); Fail_time_cnt = 0; Recode_e_code(e_rtc_fail, GetDate.Year, "req_ntp× 使用rtu时间"); } } // else // { // rt_kprintf("GetDate.Year right > %d\n" ,GetDate.Year); // } LOG_I("参数同步:lat:%s lng:%s", lat->valuestring, lng->valuestring); // CSQ if (csq != NULL && atoi(csq->valuestring) >= 0 && atoi(csq->valuestring) <= 31) { rt_sprintf(device_status.csq, "%s", csq->valuestring); } else { rt_sprintf(device_status.csq, "0"); } // 更新网线接入状态 if (link_sta != NULL && atoi(link_sta->valuestring) >= 0 && atoi(link_sta->valuestring) <= 1) { device_status.link_sta = atoi(link_sta->valuestring); LOG_I(">>>>>>>>>>>>>有线接入状态>>>>>>>>>>>>>>:%d", device_status.link_sta); } // Volume if (volume != NULL && atoi(volume->valuestring) >= 0 && atoi(volume->valuestring) <= 31) { device_status.vol = atoi(volume->valuestring); LOG_I("设置音量:%d", device_status.vol); } else { device_status.vol = 7; } // NET if (net != NULL && atoi(net->valuestring) >= 0 && atoi(net->valuestring) <= 1) { LOG_I("网络状态:%s", net->valuestring); rt_sprintf(device_status.net, "%s", net->valuestring); ReFlash_RTC(); if (GetDate.Year > 200) { Request_ntp(); } // rt_kprintf("GetDate.Year %d/n",GetDate.Year); } else { rt_sprintf(device_status.net, "1"); } // SIM if (sim != NULL && atoi(sim->valuestring) >= 0 && atoi(sim->valuestring) <= 1) { rt_sprintf(device_status.sim, "%s", sim->valuestring); } else { rt_sprintf(device_status.sim, "1"); } // GPS if (gps != NULL && atoi(gps->valuestring) >= 0 && atoi(gps->valuestring) <= 3) { rt_sprintf(device_status.gps, "%s", gps->valuestring); if (atoi(gps->valuestring) != 0) { #if BOOT_ERR == 1 if (atoi(gps->valuestring) == 1) rt_sprintf(device_status.gps_state, "%s", "GPS+BD"); if (gps_inuse != NULL) { device_status.gps_inuse = atoi(gps_inuse->valuestring); } if (gps_view != NULL) { device_status.gps_view = atoi(gps_view->valuestring); } #endif if (strstr(device_status.lat, lat->valuestring) == NULL) { memset(device_status.lat, 0, sizeof(device_status.lat)); memset(device_status.lng, 0, sizeof(device_status.lng)); rt_sprintf(device_status.lat, "%s", lat->valuestring); rt_sprintf(device_status.lng, "%s", lng->valuestring); ef_set_env_blob("lat", &device_status.lat, sizeof(device_status.lat)); // Iccid ef_set_env_blob("lng", &device_status.lng, sizeof(device_status.lng)); // Iccid } else { LOG_I("经纬度信息同步:lat-%s,lng-%s", lat->valuestring, lng->valuestring); } } else if (atoi(gps->valuestring) == 0) { memset(device_status.lat, 0, sizeof(device_status.lat)); memset(device_status.lng, 0, sizeof(device_status.lng)); rt_sprintf(device_status.lat, "%s", lat->valuestring); rt_sprintf(device_status.lng, "%s", lng->valuestring); } } else { rt_sprintf(device_status.gps, "0"); memset(device_status.lat, 0, sizeof(device_status.lat)); memset(device_status.lng, 0, sizeof(device_status.lng)); if (sizeof(device_status.lat) < 3) { sprintf(device_status.lat, "%s", "0"); sprintf(device_status.lng, "%s", "0"); } else { sprintf(device_status.lat, "%s", lat->valuestring); sprintf(device_status.lng, "%s", lng->valuestring); } } if (driver_4g != RT_NULL) sprintf(device_status.driver_4g, "%s", driver_4g->valuestring); if (project != RT_NULL) sprintf(device_status.project, "%s", project->valuestring); if (mqttcfg1 != NULL) { if (strstr("8.136.98.49", mqttcfg1->valuestring) != RT_NULL) { rt_sprintf(device_status.mqttcfg1, "8.136.98.49"); } else if (strstr("120.27.222.26", mqttcfg1->valuestring) != RT_NULL) { rt_sprintf(device_status.mqttcfg1, "120.27.222.26"); } else { rt_sprintf(device_status.mqttcfg1, "8.136.98.49"); } LOG_I("当前平台1:%s", mqttcfg1->valuestring); } if (mqttcfg2 != NULL) { sprintf(device_status.mqttcfg2, "%s", mqttcfg2->valuestring); LOG_I("当前平台2:%s", mqttcfg2->valuestring); } if (device_status.num_updata == 0) { Beep_Tip(100); } // else if (device_status.num_updata != 0 && device_status.hmi_fresh == 2) // { // if (strstr(device_status.project, "A7_DTU_V3") != RT_NULL) // { // UpLoad_Data(0); // rt_kprintf("UpLoad_Data Mark D \n\n"); // } // else // { // rt_thread_delay(2000); // UpLoad_Data(0); // rt_kprintf("UpLoad_Data Mark E \n\n"); // } // } device_status.hmi_fresh = 0; } /** * @brief 平台端下放控制指令 * */ if (item_ext != RT_NULL && strstr(item_cmd->valuestring, "paramconf") != RT_NULL) { /** * @brief 内容获取 * */ tt = cJSON_GetObjectItem(item_ext, "TT"); ts = cJSON_GetObjectItem(item_ext, "TS"); // tpl = cJSON_GetObjectItem(item_ext, "TPL"); // tph = cJSON_GetObjectItem(item_ext, "TPH"); // limit_temp = cJSON_GetObjectItem(item_ext, "limit_temp"); tpl = cJSON_GetObjectItem(item_ext, "TEMP_DOWN"); tph = cJSON_GetObjectItem(item_ext, "TEMP_UP"); limit_temp = cJSON_GetObjectItem(item_ext, "TEMP_LIMIT"); ds = cJSON_GetObjectItem(item_ext, "DS"); inr_data = cJSON_GetObjectItem(item_ext, "DATT"); inr_photo = cJSON_GetObjectItem(item_ext, "PHO_T"); if (inr_data == NULL) { inr_data = cJSON_GetObjectItem(item_ext, "DATT"); } if (inr_photo == NULL) { inr_photo = cJSON_GetObjectItem(item_ext, "PHO_T"); } limit_rain = cJSON_GetObjectItem(item_ext, "limit_rain"); collstart = cJSON_GetObjectItem(item_ext, "START_TIME"); collend = cJSON_GetObjectItem(item_ext, "END_TIME"); fan_speed = cJSON_GetObjectItem(item_ext, "fan_speed"); Demo_mode = cJSON_GetObjectItem(item_ext, "Demo_mode"); ntp_time = cJSON_GetObjectItem(item_ext, "ntp_time"); tem = cJSON_GetObjectItem(item_ext, "tem"); hum = cJSON_GetObjectItem(item_ext, "hum"); CONTROL = cJSON_GetObjectItem(item_ext, "CONTROL"); JD_Clear = cJSON_GetObjectItem(item_ext, "JD_Clear"); /** * @brief 参数设置 * */ int temp = 0; /** * @brief 光控定时 * */ if (tt != NULL) { temp = cjson_getval(tt); if (temp >= 1 && temp <= 10) { limit.LuxTime = temp; ef_set_env_blob("limit", &limit, sizeof(Limit)); rt_kprintf("光控定时tt:%d\n", temp); } else { rt_kprintf("光控定时tt设置失败参数错误!!!\n"); } } /** * @brief 工作模式 * */ if (ts != NULL) { temp = cjson_getval(ts); if (temp == 0 || temp == 1) { limit.LuxEN = temp; ef_set_env_blob("limit", &limit, sizeof(Limit)); LOG_I("定时模式ts:%d", temp); } else { LOG_E("定时模式ts设置失败参数错误!!!"); } } /** * @brief 低温保护 * */ if (tpl != NULL) { temp = cjson_getval(tpl); if (temp >= -50 && temp <= 50) { limit.temp_dw = temp; ef_set_env_blob("limit", &limit, sizeof(Limit)); rt_kprintf("低温保护tpl:%d\n", temp); } else { rt_kprintf("低温保护tpl设置失败参数错误!!! %d \n", temp); } } /** * @brief 高温保护 * */ if (tph != NULL) { temp = cjson_getval(tph); if (temp >= 50 && temp <= 80) { limit.temp_up = temp; ef_set_env_blob("limit", &limit, sizeof(Limit)); rt_kprintf("高温保护tph:%d\n", temp); } else { rt_kprintf("高温保护tph设置失败参数错误!!!\n"); } } /** * @brief 开关机状态 * */ if (ds != NULL) { temp = cjson_getval(ds); if (temp >= 0 && temp <= 1) { device_status.ds = temp; ef_set_env_blob("ds", &device_status.ds, sizeof(device_status.ds)); LOG_I("开关机状态:%d", temp); } else { LOG_E("开关机状态设置失败参数错误!!!"); } } /** * @brief 数据间隔 * */ if (inr_data != NULL) { temp = cjson_getval(inr_data); if (temp >= 5 && temp <= 120) { syscfg.dattim = temp; INR_DAT = syscfg.dattim * 60 - 10; // 减去30 消除上报所耗时间 ef_set_env_blob("syscfg", &syscfg, sizeof(syscfg)); LOG_I("数据上传间隔:%d\n", temp); } else { LOG_E("数据上传间隔设置错误!!!\n"); } } /** * @brief 照片间隔 * */ if (inr_photo != NULL) { temp = cjson_getval(inr_photo); if (temp >= 5 && temp <= 240) { syscfg.photim = temp; (syscfg.photim >= 5) ? (INR_PIC = (syscfg.photim * 60)) : (INR_PIC = (TakeINR * 60)); ef_set_env_blob("syscfg", &syscfg, sizeof(syscfg)); LOG_I("照片上传间隔:%d\n", temp); } else { LOG_E("照片上传间隔设置错误!!!\n"); } } /** * @brief 拍照定时参数: 间隔天数 + 时刻(时/分) * * {"cmd":"paramconf","ext":{"PHO_INR_DAY":3,"PHO_T_HOUR":14,"PHO_T_MIN":10}} */ { cJSON *pho_inr_day = cJSON_GetObjectItem(item_ext, "PHO_INR_DAY"); cJSON *pho_t_hour = cJSON_GetObjectItem(item_ext, "PHO_T_HOUR"); cJSON *pho_t_min = cJSON_GetObjectItem(item_ext, "PHO_T_MIN"); int photo_cfg = 0; if (pho_inr_day != NULL) { temp = cjson_getval(pho_inr_day); if (temp >= PHO_INR_DAY_MIN && temp <= PHO_INR_DAY_MAX) { syscfg.pho_inr_day = temp; photo_cfg = 1; LOG_I("拍照间隔天数:%d\n", temp); } else { LOG_E("拍照间隔天数设置错误(1-7)!!!\n"); } } if (pho_t_hour != NULL) { temp = cjson_getval(pho_t_hour); if (temp >= 0 && temp <= 23) { syscfg.pho_t_hour = temp; photo_cfg = 1; LOG_I("拍照时刻-时:%d\n", temp); } else { LOG_E("拍照时刻-时设置错误(0-23)!!!\n"); } } if (pho_t_min != NULL) { temp = cjson_getval(pho_t_min); if (temp >= 0 && temp <= 59) { syscfg.pho_t_min = temp; photo_cfg = 1; LOG_I("拍照时刻-分:%d\n", temp); } else { LOG_E("拍照时刻-分设置错误(0-59)!!!\n"); } } if (photo_cfg) { ef_set_env_blob("syscfg", &syscfg, sizeof(syscfg)); LOG_I("拍照定时已保存: %d天 %02d:%02d\n", syscfg.pho_inr_day, syscfg.pho_t_hour, syscfg.pho_t_min); } } /** * @brief 温控开关 * */ if (limit_temp != NULL) { temp = cjson_getval(limit_temp); if (temp >= 0 && temp <= 1) { limit.temhumEN = temp; ef_set_env_blob("limit", &limit, sizeof(Limit)); LOG_I("温控开关:%d", temp); } else { LOG_E("温控开关设置错误!!!"); } } /** * @brief 雨控开关 * */ if (limit_rain != NULL) { temp = cjson_getval(limit_rain); if (temp >= 0 && temp <= 1) { limit.RainEN = temp; ef_set_env_blob("limit", &limit, sizeof(Limit)); LOG_I("温控开关:%d", temp); } else { LOG_E("温控开关设置错误!!!"); } } /** * @brief 时控开始 * */ if (collstart != NULL) { temp = cjson_getval(collstart); if (temp >= 0 && temp <= 24) { device_status.collecting_sh1 = temp; ef_set_env_blob("collecting_sh1", &device_status.collecting_sh1, sizeof(device_status.collecting_sh1)); LOG_I("时控开始:%d", temp); } else { LOG_E("时控开始设置错误!!!"); } } /** * @brief 时控结束 * */ if (collend != NULL) { temp = cjson_getval(collend); if (temp >= 0 && temp <= 24) { device_status.collecting_eh1 = temp; ef_set_env_blob("collecting_eh1", &device_status.collecting_eh1, sizeof(device_status.collecting_eh1)); LOG_I("时控结束:%d", temp); } else { LOG_E("时控结束设置错误!!!"); } } /** * @brief 演示模式 * */ if (Demo_mode != NULL) { temp = cjson_getval(Demo_mode); if (temp >= 0 && temp <= 1) { Demo_Mode_NEW = temp; if (temp) LOG_I("演示模式 > 打开"); else LOG_I("演示模式 > 关闭"); } else { LOG_E("演示模式设置参数错误!!!"); return 0; } } if (CONTROL != NULL) { char temp = cjson_getval(CONTROL); if (temp >= 2) { rt_kprintf("错误的CONTROL: %d\n", temp); cJSON_Delete(root); return; } else { syscfg.en_tigmode = temp; ef_set_env_blob("syscfg", (const char *)&syscfg, sizeof(syscfg)); rt_kprintf("Change Workmod %d OK\n", temp); LOG_I("CONTROL: %d\n", temp); Get_work_mode(); } } if (ntp_time != NULL && (strlen(ntp_time->valuestring) == 14)) { rt_kprintf(" ntp_time get time >> %s \n\n", ntp_time->valuestring); struct tm ntptime = {0}; char year_s[5], month_s[3], day_s[3], hour_s[3], min_s[3], sec_s[3]; strncpy(year_s, ntp_time->valuestring, 4); strncpy(month_s, ntp_time->valuestring + 4, 2); strncpy(day_s, ntp_time->valuestring + 6, 2); strncpy(hour_s, ntp_time->valuestring + 8, 2); strncpy(min_s, ntp_time->valuestring + 10, 2); strncpy(sec_s, ntp_time->valuestring + 12, 2); ntptime.tm_year = atoi(year_s); ntptime.tm_mon = atoi(month_s); ntptime.tm_mday = atoi(day_s); ntptime.tm_hour = atoi(hour_s); ntptime.tm_min = atoi(min_s); ntptime.tm_sec = atoi(sec_s); EXE_NTP_SETTIME(&ntptime); cJSON_Delete(root); return 0; } else if (ntp_time != NULL) { rt_kprintf(" ntp_time illagl >> %s \n\n", ntp_time->valuestring); } if (tem != NULL && hum != NULL) { strncpy(device_status.tempture, tem->valuestring, 4); strncpy(device_status.humidity, hum->valuestring, 4); rt_kprintf("tem %s >> hum %s \n\n", device_status.tempture, device_status.humidity); cJSON_Delete(root); return 0; } if(JD_Clear != NULL) { char temp = cjson_getval(JD_Clear); if(temp == 1) { RTC_SET_TigVal(0); Recode_e_code(e_CNT_RESET, 2, "平台清空计数"); } } UpLoad_Data(0); // 指令下发后回复 rt_thread_delay(2000); MA_save(); rt_thread_delay(1000); } } cJSON_Delete(root); } return 0; } /** * @brief 执行上报状态信息json的动作 * * 0-数据上报 1-指令响应 2-计数上报 */ void UpLoad_Data(uint8_t type) { char *updata; if (type == 0) { updata = makeJson_NEW(0); // 上报数据时 } else { updata = makeJson_NEW(type); // 刷新状态时 } if (strlen(updata) > 5 && updata != NULL) { rt_kprintf("upload data:%d %s type %d \n", rt_strlen(updata), updata, type); DTU_Write("%s", updata); rt_free(updata); list_mem(); } // 播放数据上传中语音 } void updata(void) { UpLoad_Data(0); } MSH_CMD_EXPORT(updata, updata);