| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2025-03-27 RuoFeng the first version
- */
- /*********************↑ declaration ↑************************/
- /**
- *
- *
- *
- *
- * */
- /*********************↓ define ↓************************/
- #define DBG_ENABLE
- #define DBG_COLOR
- #define DBG_TAG "tn"
- #define DBG_LEVEL DBG_INFO
- #include <rtdbg.h>
- #define RSSI_TO_DBM(rssi) (2 * (rssi) - 113)
- /*********************↑ define ↑************************/
- /**
- *
- *
- *
- *
- * */
- /*********************↓ include ↓************************/
- #include <rtthread.h>
- #include "rs485.h"
- #include "dtu_uart2.h"
- #include "string.h"
- #include "control.h"
- #include <Work_SY2.h>
- #include <easyflash.h>
- #include "protocol.h"
- #include "test.h"
- #include "cJSON.h"
- /*********************↑ include ↑************************/
- /**
- *
- *
- *
- *
- * */
- /*********************↓ extern ↓************************/
- extern uint8_t ReFlash_RTC(void);
- extern Device_Status_typedef device_status;
- extern RTC_DateTypeDef GetDate;
- extern RTC_TimeTypeDef GetTime;
- extern Sensor sensor[MAX_SENSOR_NUM];
- extern JD_Test_Sta jts;
- extern int cjson_getval(cJSON *json);
- extern Limit limit;
- extern uint16_t RayTigCnt;
- extern char CamFree;
- /*********************↑ extern ↑************************/
- /**
- *
- *
- *
- *
- * */
- /********************↓ declaration ↓***********************/
- /********************↑ declaration ↑***********************/
- /**
- *
- *
- *
- *
- * */
- /*********************↓ global variables ↓************************/
- static struct RES_Type res_c = {0};
- /*********************↑ global variables ↑************************/
- /**
- *
- *
- *
- *
- * */
- /**
- * @brief Get the Timing object 获取时间戳
- *
- * @param str
- */
- void GetTiming(char *str, char len)
- {
- ReFlash_RTC();
- if (len < 28)
- {
- rt_kprintf("GetTiming > str so short %d\n", len);
- return;
- }
- sprintf(str, "%04d-%02d-%02dT%02d:%02d:%02d.%03d",
- (GetDate.Year % 2000) + 2000,
- GetDate.Month,
- GetDate.Date,
- GetTime.Hours,
- GetTime.Minutes,
- GetTime.Seconds,
- 0);
- }
- /**
- * @brief Get the now temphumi object
- *
- * @param temp
- * @param humi
- */
- void get_now_temphumi(char *temp_c , char *humi_c)
- {
- if (sensor[s_Temp].online && strstr(sensor[s_Temp].eValue, "99.99") == NULL)
- {
- sprintf(temp_c , "%s" , sensor[s_Temp].eValue);
- }
- else
- {
- sprintf(temp_c , "%s" , device_status.tempture);
- }
- if (sensor[s_Humi].online && strstr(sensor[s_Humi].eValue, "99.99") == NULL)
- {
- sprintf(humi_c , "%s" , sensor[s_Humi].eValue);
- }
- else
- {
- sprintf(humi_c , "%s" , device_status.humidity);
- }
-
- }
- extern char Demo_Mode_NEW;
- extern SYSCFG syscfg;
- extern wm_Def workmode;
- /**
- * @brief 生成新版的状态数据包
- *
- * @return char* 直接以字符串的形式返回
- */
- char *makeJson_NEW(uint8_t type)
- {
- char cache[128] = {0};
- // 创建根JSON对象
- cJSON *root = cJSON_CreateObject();
- if (!root)
- return NULL;
- // 添加字符串类型字段
- cJSON_AddStringToObject(root, "DEVICE_SERIAL_NUMBER", device_status.imei);
- if (type == 1)
- {
- cJSON_AddStringToObject(root, "ACTION_ID", res_c.ACTION_ID);
- cJSON_AddStringToObject(root, "COMMAND", res_c.COMMAND);
- GetTiming(res_c.TIMING, sizeof(res_c.TIMING));
- cJSON_AddStringToObject(root, "TIMING", res_c.TIMING);
- cJSON_AddStringToObject(root, "RESULT", res_c.RESULT);
- }
- cJSON_AddStringToObject(root, "SIM", device_status.iccid);
- // sprintf(cache, "%d", RSSI_TO_DBM(atoi(device_status.csq)));
- cJSON_AddStringToObject(root, "SIGNAL", device_status.csq);
- sprintf(cache, "%s,%s", device_status.lng, device_status.lat);
- cJSON_AddStringToObject(root, "LOCATION", cache);
- (atoi(device_status.net) == 0) ? cJSON_AddStringToObject(root, "STATUS", "STATUS_ONLINE") : cJSON_AddStringToObject(root, "STATUS", "STATUS_OFFLINE");
- cJSON_AddStringToObject(root, "STATUS_DESCRIPTION", "设备运行正常"); // 需要修改 // 但是好像没有异常的时候啊 先不改
- GetTiming(cache, sizeof(cache));
- cJSON_AddStringToObject(root, "UPDATE_DATE", cache);
- // 添加数值类型字段
- cJSON_AddNumberToObject(root, "VOLTAGE", atof(device_status.voltage));
- cJSON_AddNumberToObject(root, "CURRENT", atof(device_status.power));
- char temp_c[6] = {0};
- char humi_c[6] = {0};
- get_now_temphumi(temp_c , humi_c);
- cJSON_AddNumberToObject(root, "TEMPERATURE", atof(temp_c));
- cJSON_AddNumberToObject(root, "HUMIDITY", atof(humi_c));
- // cJSON_AddNumberToObject(root, "TPS", device_status.temp_status);
- // cJSON_AddNumberToObject(root, "RPS", device_status.rain_status);
- cJSON_AddNumberToObject(root, "DEMO", Demo_Mode_NEW);
- cJSON_AddNumberToObject(root, "REMAIN", Get_REMAIN());
- sprintf(cache, "%d", syscfg.dattim);
- cJSON_AddStringToObject(root, "DATT", cache);
- sprintf(cache, "%d", syscfg.pho_inr_day);
- cJSON_AddStringToObject(root, "PHO_INR_DAY", cache);
- sprintf(cache, "%d", syscfg.pho_t_hour);
- cJSON_AddStringToObject(root, "PHO_T_HOUR", cache);
- sprintf(cache, "%d", syscfg.pho_t_min);
- cJSON_AddStringToObject(root, "PHO_T_MIN", cache);
- sprintf(cache, "%d", limit.temhumEN);
- cJSON_AddStringToObject(root, "TEMP_LIMIT", cache);
- sprintf(cache, "%d", limit.temp_up);
- cJSON_AddStringToObject(root, "TEMP_UP", cache);
- sprintf(cache, "%d", limit.temp_dw);
- cJSON_AddStringToObject(root, "TEMP_DOWN", cache);
- Get_work_mode();
- sprintf(cache, "%d", workmode);
- cJSON_AddStringToObject(root, "CONTROL", cache);
- sprintf(cache, "%s-%s", VERSION_NUM, device_status.driver_4g);
- cJSON_AddStringToObject(root, "VERSION", cache);
- cJSON_AddStringToObject(root, "HISTORY_DATA", "0");
- if (type == 2 || type == 3 || type == 4)
- {
- if (type != 4)
- {
- CamFree = 1; // 拍照完成
- }
-
- if(type == 4)
- {
- cJSON_AddStringToObject(root, "PIC_RES", "START");
- if(device_status.camsta == 0)
- {
- cJSON_AddStringToObject(root, "CAM_STA", "linkup");
- }
- else
- {
- cJSON_AddStringToObject(root, "CAM_STA", "linkdown");
- }
- }
- else
- {
- (type == 2) ? cJSON_AddStringToObject(root, "PIC_RES", "SUCC") : cJSON_AddStringToObject(root, "PIC_RES", "FAIL");
- }
-
- }
- // 生成紧凑型JSON字符串
- char *json_str = cJSON_PrintUnformatted(root);
- // 清理cJSON对象
- cJSON_Delete(root);
- DTU_Write(json_str);
- rt_kprintf("DTU_Write > %s \n\n", json_str);
- if (json_str)
- {
- free(json_str);
- }
- return NULL; // 返回的字符串需由调用者释放
- }
- /**
- * @brief 组包返回执行结果
- *
- * @param result
- * @return char* 一定要记得释放指针
- */
- char *ReportRes(uint8_t result)
- {
- // 创建根JSON对象
- cJSON *root = cJSON_CreateObject();
- if (!root)
- {
- rt_kprintf("Failed to create JSON root\n");
- return NULL;
- }
- if (strstr(res_c.COMMAND, "00") == NULL)
- {
- return NULL;
- }
- // 添加字段到根对象
- cJSON_AddStringToObject(root, "DEVICE_SERIAL_NUMBER", device_status.imei);
- cJSON_AddStringToObject(root, "ACTION_ID", res_c.ACTION_ID);
- cJSON_AddStringToObject(root, "COMMAND", res_c.COMMAND);
- GetTiming(res_c.TIMING, sizeof(res_c.TIMING));
- cJSON_AddStringToObject(root, "TIMING", res_c.TIMING);
- result ? cJSON_AddStringToObject(root, "RESULT", "SUCC") : cJSON_AddStringToObject(root, "RESULT", "FAIL");
- // 将JSON对象转换为字符串(格式化输出)
- char *json_str = cJSON_PrintUnformatted(root);
- // 清理cJSON对象
- cJSON_Delete(root);
- DTU_Write(json_str);
- rt_kprintf("DTU_Write > %s \n\n", json_str);
- if (json_str)
- {
- free(json_str);
- }
- return NULL;
- }
- /**
- * @brief 回复结果
- *
- */
- static void Report_setpara(void)
- {
- // 创建根JSON对象
- cJSON *root = cJSON_CreateObject();
- if (!root)
- {
- rt_kprintf("Failed to create JSON root\n");
- return;
- }
- if (strstr(res_c.COMMAND, "00") == NULL)
- {
- return;
- }
- // 添加字段到根对象
- cJSON_AddStringToObject(root, "DEVICE_SERIAL_NUMBER", device_status.imei);
- cJSON_AddStringToObject(root, "ACTION_ID", res_c.ACTION_ID);
- cJSON_AddStringToObject(root, "COMMAND", res_c.COMMAND);
- GetTiming(res_c.TIMING, sizeof(res_c.TIMING));
- cJSON_AddStringToObject(root, "TIMING", res_c.TIMING);
- cJSON_AddStringToObject(root, "RESULT", "SUCC");
- cJSON_AddNumberToObject(root, "CONTROL", limit.LuxEN);
- char cache_0[8] = {0};
- char cache_1[8] = {0};
- char cache_2[8] = {0};
- sprintf(cache_0, "%d", syscfg.pho_inr_day);
- sprintf(cache_1, "%d", syscfg.pho_t_hour);
- sprintf(cache_2, "%d", syscfg.pho_t_min);
- cJSON_AddStringToObject(root, "PHO_INR_DAY", cache_0);
- cJSON_AddStringToObject(root, "PHO_T_HOUR", cache_1);
- cJSON_AddStringToObject(root, "PHO_T_MIN", cache_2);
- sprintf(cache_0, "%d", syscfg.dattim);
- cJSON_AddStringToObject(root, "DATT", cache_0);
- // 将JSON对象转换为字符串(格式化输出)
- char *json_str = cJSON_PrintUnformatted(root);
- // 清理cJSON对象
- cJSON_Delete(root);
- DTU_Write(json_str);
- rt_kprintf("DTU_Write > %s \n\n", json_str);
- if (json_str)
- {
- free(json_str);
- }
- }
- /**
- * @brief 执行新协议下发的指令 dev_setpara
- *
- * @param cmd json字符串
- */
- static void exe_dev_setpara(char *cmd)
- {
- // 解析JSON根对象
- cJSON *root = cJSON_Parse(cmd);
- if (root == NULL)
- {
- const char *error_ptr = cJSON_GetErrorPtr();
- if (error_ptr != NULL)
- {
- rt_kprintf("JSON解析错误: %s\n", error_ptr);
- }
- return;
- }
- /**
- * @brief 应用模式
- *
- */
- cJSON *CONTROL = cJSON_GetObjectItemCaseSensitive(root, "CONTROL");
- 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);
- }
- }
- /**
- * @brief 开始时间
- *
- */
- cJSON *START_TIME = cJSON_GetObjectItemCaseSensitive(root, "START_TIME");
- if (cJSON_IsString(START_TIME) && (strlen(START_TIME->valuestring) < 3))
- {
- char temp = cjson_getval(START_TIME);
- 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("START_TIME: %s\n", START_TIME->valuestring);
- }
- else
- {
- LOG_E("时控开始设置错误!!!");
- }
- }
- /**
- * @brief 结束时间
- *
- */
- cJSON *END_TIME = cJSON_GetObjectItemCaseSensitive(root, "END_TIME");
- if (cJSON_IsString(END_TIME) && (strlen(START_TIME->valuestring) < 3))
- {
- char temp = cjson_getval(END_TIME);
- 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("END_TIME: %s\n", END_TIME->valuestring);
- }
- else
- {
- LOG_E("时控结束设置错误!!!");
- }
- }
- /**
- * @brief 图片间隔
- *
- */
- cJSON *PHO_T = cJSON_GetObjectItemCaseSensitive(root, "PHO_T");
- if (cJSON_IsString(PHO_T))
- {
- char temp = cjson_getval(PHO_T);
- if (temp >= 5 && temp <= 240)
- {
- syscfg.photim = temp;
- ef_set_env_blob("syscfg", &syscfg, sizeof(syscfg));
- LOG_I("照片上传间隔:%d\n", temp);
- }
- else
- {
- LOG_E("照片上传间隔设置错误!!!\n");
- }
- }
- /**
- * @brief 数据间隔
- *
- */
- cJSON *DATT = cJSON_GetObjectItemCaseSensitive(root, "DATT");
- if (cJSON_IsString(DATT) && (strlen(DATT->valuestring) < 3))
- {
- char temp = cjson_getval(DATT);
- if (temp >= 10 && temp <= 120)
- {
- syscfg.dattim = temp;
- ef_set_env_blob("syscfg", &syscfg, sizeof(syscfg));
- LOG_I("DATT: %s\n", DATT->valuestring);
- }
- else
- {
- LOG_E("数据上传间隔设置错误!!!\n");
- }
- }
- cJSON_Delete(root);
- Report_setpara();
- }
- /**
- * @brief 执行具体的指令 并回复结果
- *
- */
- static void execute_NewCmd(char *cmd)
- {
- if (atoi(res_c.COMMAND) > dev_typemax)
- {
- rt_kprintf("execute_NewCmd Err %s \n", res_c.COMMAND);
- return;
- }
- switch (atoi(res_c.COMMAND))
- {
- case dev_on:
- Recode_e_code(e_CMD_list, dev_on, "下发指令执行");
- device_status.ds = ON;
- ef_set_env_blob("ds", &device_status.ds, sizeof(device_status.ds));
- ef_get_env_blob("ds", &device_status.ds, sizeof(device_status.ds), NULL);
- if (device_status.ds == ON)
- {
- rt_kprintf("dev_on execute\n");
- ReportRes(1);
- }
- else
- {
- ReportRes(0);
- device_status.ds = ON;
- ef_set_env_blob("ds", &device_status.ds, sizeof(device_status.ds));
- }
- break;
- case dev_off:
- Recode_e_code(e_CMD_list, dev_off, "下发指令执行");
- device_status.ds = OFF;
- ef_set_env_blob("ds", &device_status.ds, sizeof(device_status.ds));
- ef_get_env_blob("ds", &device_status.ds, sizeof(device_status.ds), NULL);
- if (device_status.ds == OFF)
- {
- rt_kprintf("dev_off execute\n");
- ReportRes(1);
- }
- else
- {
- ReportRes(0);
- device_status.ds = OFF;
- ef_set_env_blob("ds", &device_status.ds, sizeof(device_status.ds));
- }
- break;
- case dev_reboot:
- Recode_e_code(e_CMD_list, dev_reboot, "下发指令执行");
- ReportRes(1);
- rt_kprintf("dev_reboot execute\n");
- rt_hw_cpu_reset();
- break;
- case dev_takepho:
- Recode_e_code(e_CMD_list, dev_takepho, "下发指令执行");
- jts.takephoto_test = ON;
- ReportRes(1);
- rt_kprintf("dev_takepho execute\n");
- break;
- case dev_sta:
- Recode_e_code(e_CMD_list, dev_sta, "下发指令执行");
- rt_kprintf("dev_sta execute\n");
- makeJson_NEW(1);
- break;
- case dev_readcfg:
- Recode_e_code(e_CMD_list, dev_readcfg, "下发指令执行");
- // rtu进行回复
- break;
- case dev_setcfg:
- Recode_e_code(e_CMD_list, dev_setcfg, "下发指令执行");
- // rtu进行回复
- break;
- case dev_setpara:
- Recode_e_code(e_CMD_list, dev_setpara, "下发指令执行");
- exe_dev_setpara(cmd);
- break;
- default:
- break;
- }
- }
- /**
- * @brief 解析新协议的指令
- *
- * @param cmd 待解析的JSON字符串
- */
- void prase_NewCmd(char *cmd)
- {
- // 校验输入有效性
- if (cmd == NULL)
- {
- rt_kprintf("输入字符串为空\n");
- return;
- }
- // 解析JSON根对象
- cJSON *root = cJSON_Parse(cmd);
- if (root == NULL)
- {
- const char *error_ptr = cJSON_GetErrorPtr();
- if (error_ptr != NULL)
- {
- rt_kprintf("JSON解析错误: %s\n", error_ptr);
- }
- return;
- }
- // 解析设备序列号
- cJSON *device_sn = cJSON_GetObjectItemCaseSensitive(root, "DEVICE_SERIAL_NUMBER");
- if (cJSON_IsString(device_sn) && (device_sn->valuestring != NULL))
- {
- rt_kprintf("设备序列号: %s\n", device_sn->valuestring);
- if (strlen(device_sn->valuestring) != 15)
- {
- rt_kprintf("错误的序列号: %s %d\n", device_sn->valuestring, strlen(device_sn->valuestring));
- cJSON_Delete(root);
- return;
- }
- }
- else
- {
- rt_kprintf("未找到DEVICE_SERIAL_NUMBER字段或类型错误\n");
- cJSON_Delete(root);
- return;
- }
- // 解析指令ID
- cJSON *action_id = cJSON_GetObjectItemCaseSensitive(root, "ACTION_ID");
- if (cJSON_IsString(action_id) && (action_id->valuestring != NULL))
- {
- rt_kprintf("指令ID: %s\n", action_id->valuestring);
- sprintf(res_c.ACTION_ID, "%s", action_id->valuestring);
- }
- else
- {
- rt_kprintf("未找到ACTION_ID字段或类型错误\n");
- }
- // 解析指令代码
- cJSON *command = cJSON_GetObjectItemCaseSensitive(root, "COMMAND");
- if (cJSON_IsString(command) && (command->valuestring != NULL))
- {
- rt_kprintf("指令代码: %s\n", command->valuestring);
- if (atoi(command->valuestring) >= dev_typemax)
- {
- rt_kprintf("错误的指令代码: %s\n", command->valuestring);
- }
- else
- {
- sprintf(res_c.COMMAND, "%s", command->valuestring);
- }
- }
- else
- {
- rt_kprintf("未找到COMMAND字段或类型错误\n");
- }
- // 解析执行时间
- cJSON *timing = cJSON_GetObjectItemCaseSensitive(root, "TIMING");
- if (cJSON_IsString(timing) && (timing->valuestring != NULL))
- {
- rt_kprintf("执行时间: %s\n", timing->valuestring);
- }
- else
- {
- rt_kprintf("未找到TIMING字段或类型错误\n");
- }
- // 释放JSON对象
- cJSON_Delete(root);
- /*** 开始执行具体指令 ***/
- execute_NewCmd(cmd);
- /*** 开始执行具体指令 ***/
- }
|