parseDeviceMessage.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. #include "parseDeviceMessage.h"
  2. #include "cJson.h"
  3. #include "systick.h"
  4. #include "usart.h"
  5. #include "string.h"
  6. #include <math.h>
  7. #include "mqttRecv.h"
  8. #include "log.h"
  9. #include "ec800m.h"
  10. #include "main.h"
  11. #define MQTT_SUB_CMD_WRITE 0
  12. #define MQTT_SUB_CMD_READ 1
  13. ring_buffer mqttRecv;
  14. void processHTTPjson(cJSON *json);
  15. char *processStringData(cJSON *data_obj, const char *key);
  16. int processIntData(cJSON *data_obj, const char *key);
  17. void processHttp(uint8_t *data);
  18. static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr);
  19. //static void extract_data_from_buffer232(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr);
  20. static uint16_t checksum(const char *str, uint16_t len);
  21. // json解析字符串
  22. char *processStringData(cJSON *data_obj, const char *key)
  23. {
  24. cJSON *json_data = cJSON_GetObjectItemCaseSensitive(data_obj, key);
  25. if (cJSON_IsString(json_data) && (json_data->valuestring != NULL))
  26. {
  27. return json_data->valuestring;
  28. }
  29. else
  30. {
  31. return NULL;
  32. }
  33. }
  34. // json解析int
  35. int processIntData(cJSON *data_obj, const char *key)
  36. {
  37. cJSON *json_data = cJSON_GetObjectItemCaseSensitive(data_obj, key);
  38. // if (cJSON_IsNumber(json_data) && (json_data->valueint != NULL)) 解决寄存器地址为0问题
  39. if (cJSON_IsNumber(json_data))
  40. {
  41. return json_data->valueint;
  42. }
  43. else
  44. {
  45. // gateway.data_valid_flag = 0; // 如果任意数据为NULL则此次数据为无效
  46. return -1;
  47. }
  48. }
  49. /*
  50. * 函数名:void WaitForUpData(void)
  51. * 输入参数:无
  52. * 输出参数:无
  53. * 返回值:无
  54. * 函数作用:等待更新本地flash信息
  55. */
  56. bool WaitForUpData(void)
  57. {
  58. if (UART0_RX_STAT > 0)
  59. {
  60. UART0_RX_STAT = 0;
  61. uint32_t len;
  62. uint16_t checkCode;
  63. extract_data_from_buffer(UART0_RX_BUF, &len, &checkCode);
  64. uint16_t jsonCheck = checksum(UART0_RX_BUF, len);
  65. if (checkCode == jsonCheck)
  66. {
  67. memset(UART0_RX_BUF + len, 0, sizeof(UART0_RX_BUF) - len);
  68. if(UART0_RX_NUM<1024)
  69. {
  70. cJSON *json = cJSON_Parse(UART0_RX_BUF);
  71. if (json != NULL)
  72. {
  73. processHTTPjson(json);
  74. cJSON_Delete(json);
  75. Clear_DMA_Buffer();
  76. return true;
  77. }
  78. else
  79. {
  80. cJSON_Delete(json);
  81. Clear_DMA_Buffer();
  82. LogPrint(LOG_INFO, __func__, __LINE__, "json is to long");
  83. return false;
  84. }
  85. }
  86. else
  87. {
  88. processHttp(UART0_RX_BUF);
  89. }
  90. }
  91. }
  92. }
  93. /*
  94. * 函数名:static void extract_data_from_buffer(const char* buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
  95. * 输入参数:buffer字符串
  96. * 输出参数:json有效字符串长度len_ptr,checkCode_ptr校验码指针
  97. * 返回值:无
  98. * 函数作用:eg. QFDWL: 621,3e23 从json信息最后端取出这段json的有效长度和校验码
  99. */
  100. static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
  101. {
  102. char *start = strstr(buffer, "+QFDWL:");
  103. if (start != NULL)
  104. {
  105. start += 8; // 跳过"+QFDWL:"
  106. uint32_t len = 0;
  107. sscanf(start, "%u,", &len); // 读取长度
  108. start = strchr(start, ',') + 1; // 跳过逗号
  109. uint16_t checkCode = 0;
  110. sscanf(start, "%hx", &checkCode); // 读取16进制数据
  111. // 将提取的数据存入形参
  112. *len_ptr = len;
  113. *checkCode_ptr = checkCode;
  114. }
  115. }
  116. /*
  117. * 函数名:void processHTTPjson(cJSON *json)
  118. * 输入参数:json从http get获取的json字符串
  119. * 输出参数:无
  120. * 返回值:无
  121. * 函数作用:解析json字符串将设备配置信息写到flash中 strcpy NULL指针导致的内存泄露问题
  122. */
  123. void processHTTPjson(cJSON *json)
  124. {
  125. CONFIG_PARAMS gateway;
  126. gateway.data_valid_flag = 0xF1; // 将数据标识位置为有效
  127. cJSON *readArrayItem = cJSON_GetObjectItem(json, "sensorData");
  128. gateway.device_read_data_num = cJSON_GetArraySize(readArrayItem);
  129. cJSON *writeArrayItem = cJSON_GetObjectItem(json, "commandData");
  130. gateway.device_write_data_num = cJSON_GetArraySize(writeArrayItem);
  131. strcpy(gateway.host, processStringData(json, "host"));
  132. gateway.port = processIntData(json, "port");
  133. //strcpy(gateway.deviceId, processStringData(json, "deviceId")); 这条数据将不在进行解析由芯片id决定
  134. strcpy(gateway.messageTopic, processStringData(json, "messageTopic"));
  135. strcpy(gateway.commandTopic, processStringData(json, "commandTopic"));
  136. gateway.dataSource = processIntData(json, "dataSource");
  137. gateway.baudrate = processIntData(json, "baudrate");
  138. gateway.dataBits = processIntData(json, "dataBit");
  139. gateway.stopBit = processIntData(json, "stopBit");
  140. gateway.checkBit = processIntData(json, "checkBit");
  141. gateway.flowControl = processIntData(json, "flowControl");
  142. gateway.dataType645 = processIntData(json, "version645");
  143. gateway.inboundTime= processIntData(json, "inboundTime");
  144. gateway.pollTime= processIntData(json, "pollTime");
  145. if (cJSON_IsArray(readArrayItem))
  146. {
  147. for (int i = 0; i < gateway.device_read_data_num; i++)
  148. {
  149. cJSON *read_data_obj = cJSON_GetArrayItem(readArrayItem, i);
  150. if (cJSON_IsObject(read_data_obj))
  151. {
  152. if (gateway.dataSource == MODBUS)
  153. {
  154. strcpy(gateway.device_read_data[i].deviceId, processStringData(read_data_obj, "deviceId"));
  155. strcpy(gateway.device_read_data[i].keyword, processStringData(read_data_obj, "identifier"));
  156. gateway.device_read_data[i].mdbSlave = processIntData(read_data_obj, "slaveAddress");
  157. gateway.device_read_data[i].mdbRegister = processIntData(read_data_obj, "registerAddress");
  158. gateway.device_read_data[i].mdbFunctionCode = processIntData(read_data_obj, "rFunctionCode");
  159. gateway.device_read_data[i].registerLength = processIntData(read_data_obj, "registerByteNum");
  160. gateway.device_read_data[i].decimalPoint = processIntData(read_data_obj, "precise");
  161. gateway.device_read_data[i].bigLittleFormat=processIntData(read_data_obj,"bigLittleFormat");
  162. }
  163. else if (gateway.dataSource == DLT645)
  164. {
  165. strcpy(gateway.device_read_data[i].deviceId, processStringData(read_data_obj, "deviceId"));
  166. strcpy(gateway.device_read_data[i].keyword, processStringData(read_data_obj, "identifier"));
  167. gateway.device_read_data[i].dataType645 = processIntData(read_data_obj, "identifier645");
  168. char idstring[13];
  169. strcpy(idstring, processStringData(read_data_obj, "deviceID645"));
  170. // 将deviceID645 由string变成0x
  171. for (int j = 0; j < 6; j++)
  172. {
  173. {
  174. uint8_t byte;
  175. sscanf((const char *)&idstring[j * 2], "%2hhx", &byte);
  176. gateway.device_read_data[i].deviceID645[j] = byte;
  177. }
  178. }
  179. }
  180. }
  181. }
  182. //写数据预存数组
  183. for (int i = 0; i < gateway.device_write_data_num; i++)
  184. {
  185. cJSON *write_data_obj = cJSON_GetArrayItem(writeArrayItem, i);
  186. if (gateway.dataSource == MODBUS)
  187. {
  188. strcpy(gateway.device_write_data[i].deviceId, processStringData(write_data_obj, "deviceId"));
  189. strcpy(gateway.device_write_data[i].keyword, processStringData(write_data_obj, "identifier"));
  190. gateway.device_write_data[i].mdbSlave = processIntData(write_data_obj, "slaveAddress");
  191. gateway.device_write_data[i].mdbRegister = processIntData(write_data_obj, "registerAddress");
  192. gateway.device_write_data[i].mdbFunctionCode = processIntData(write_data_obj, "wFunctionCode");
  193. gateway.device_write_data[i].registerLength = processIntData(write_data_obj, "registerByteNum");
  194. gateway.device_write_data[i].decimalPoint = processIntData(write_data_obj, "precise");
  195. gateway.device_write_data[i].bigLittleFormat=processIntData(write_data_obj,"bigLittleFormat");
  196. }
  197. }
  198. }
  199. save_config_params(&gateway);
  200. }
  201. //提取int数据
  202. int parseIntField(const char* data, const char* field) {
  203. char* ptr = strstr(data, field) + strlen(field);
  204. int value;
  205. value = strtol(ptr, &ptr, 10);
  206. return value;
  207. }
  208. //提取string字符串
  209. void parseStringField(const char* data, const char* field, char* value) {
  210. char* ptr = strstr(data, field) + strlen(field) ;
  211. sscanf(ptr, "%[^\"],", value);
  212. }
  213. void parseCommandData();
  214. void processHttp(uint8_t *data)
  215. {
  216. CONFIG_PARAMS gateway;
  217. gateway.data_valid_flag = 0xF1;
  218. char* ptr = (char*)data;
  219. gateway.dataSource=parseIntField(ptr,"\"dataSource\":");
  220. gateway.baudrate=parseIntField(ptr,"\"baudrate\":");
  221. gateway.checkBit=parseIntField(ptr,"\"checkBit\":");
  222. parseStringField(ptr,"\"commandTopic\":\"",(char *)&gateway.commandTopic);
  223. gateway.dataBits=parseIntField(ptr,"\"dataBit\":");
  224. parseStringField(ptr,"\"deviceId\":\"",(char *)&gateway.deviceId);
  225. parseStringField(ptr,"\"host\":\"",(char *)&gateway.host);
  226. gateway.inboundTime=parseIntField(ptr,"\"inboundTime\":");
  227. parseStringField(ptr,"\"messageTopic\":\"",(char *)&gateway.messageTopic);
  228. gateway.pollTime=parseIntField(ptr,"\"pollTime\":");
  229. gateway.port=parseIntField(ptr,"\"port\":");
  230. if(gateway.dataSource==2) //为MODBUS
  231. {
  232. ptr = strstr(ptr, "\"commandData\":[");
  233. int i=0;
  234. while(1)
  235. {
  236. gateway.device_write_data[i].bigLittleFormat=parseIntField(ptr,"\"bigLittleFormat\":");
  237. parseStringField(ptr,"\"deviceId\":\"",(char *)&gateway.device_write_data[i].deviceId);
  238. parseStringField(ptr,"\"identifier\":\"",(char *)&gateway.device_write_data[i].keyword);
  239. gateway.device_write_data[i].registerLength =parseIntField(ptr,"\"registerByteNum\":\"");
  240. gateway.device_write_data[i].mdbRegister=parseIntField(ptr,"\"registerAddress\":");
  241. gateway.device_write_data[i].mdbSlave =parseIntField(ptr,"\"slaveAddress\":");
  242. gateway.device_write_data[i].mdbFunctionCode=parseIntField(ptr,"\"wFunctionCode\":");
  243. ptr=strstr(ptr,"}"); //移动位置到结束
  244. ptr++;
  245. if(ptr[0]==']')
  246. {
  247. i++;
  248. gateway.device_write_data_num=i;
  249. ptr = (char*)data;
  250. break;
  251. }
  252. ptr = strchr(ptr, ',');
  253. if (!ptr)
  254. {
  255. i++;
  256. gateway.device_write_data_num=i;
  257. ptr = (char*)data;
  258. break;
  259. }
  260. i++;
  261. }
  262. ptr=strstr(ptr,"\"sensorData\":[");
  263. i=0;
  264. while(*ptr != ']')
  265. {
  266. gateway.device_read_data[i].bigLittleFormat=parseIntField(ptr,"\"bigLittleFormat\":");
  267. parseStringField(ptr,"\"deviceId\":\"",(char *)&gateway.device_read_data[i].deviceId);
  268. parseStringField(ptr,"\"identifier\":\"",(char *)&gateway.device_read_data[i].keyword);
  269. gateway.device_read_data[i].mdbRegister=parseIntField(ptr,"\"registerAddress\":");
  270. gateway.device_read_data[i].mdbSlave =parseIntField(ptr,"\"slaveAddress\":");
  271. gateway.device_read_data[i].registerLength =parseIntField(ptr,"\"registerByteNum\":");
  272. gateway.device_read_data[i].mdbFunctionCode=parseIntField(ptr,"\"rFunctionCode\":");
  273. gateway.device_read_data[i].decimalPoint=parseIntField(ptr,"\"precise\":");
  274. ptr=strstr(ptr,"}"); //移动位置到结束
  275. ptr++;
  276. if(ptr[0]==']')
  277. {
  278. i++;
  279. gateway.device_read_data_num=i;
  280. ptr = (char*)data;
  281. break;
  282. }
  283. ptr = strchr(ptr, ',');
  284. if (!ptr)
  285. {
  286. i++;
  287. gateway.device_read_data_num=i;
  288. ptr = (char*)data;
  289. break;
  290. }
  291. i++;
  292. }
  293. }
  294. else if(gateway.dataSource==1) //为dlt645协议
  295. {
  296. gateway.dataType645=parseIntField(ptr,"\"version645\":");
  297. ptr=strstr(ptr,"\"sensorData\":[");
  298. int i=0;
  299. while(*ptr != ']')
  300. {
  301. char *string=malloc(13);
  302. parseStringField(ptr,"\"deviceID645\":\"",string);
  303. for (int j = 0; j < 6; j++)
  304. {
  305. {
  306. uint8_t byte;
  307. sscanf((const char *)&string[j * 2], "%2hhx", &byte);
  308. gateway.device_read_data[i].deviceID645[j] = byte;
  309. }
  310. }
  311. free(string);
  312. parseStringField(ptr, "\"deviceId\":\"",(char *)&gateway.device_read_data[i].deviceId);
  313. parseStringField(ptr, "\"identifier\":\"",(char *)&gateway.device_read_data[i].keyword);
  314. gateway.device_read_data[i].dataType645=parseIntField(ptr,"\"identifier645\":");
  315. ptr=strstr(ptr,"}");
  316. ptr++;
  317. if(ptr[0]==']')
  318. {
  319. i++;
  320. gateway.device_read_data_num=i;
  321. ptr = (char*)data;
  322. break;
  323. }
  324. ptr = strchr(ptr, ',');
  325. if (!ptr)
  326. {
  327. i++;
  328. gateway.device_read_data_num=i;
  329. ptr = (char*)data;
  330. break;
  331. }
  332. i++;
  333. }
  334. }
  335. ptr=NULL;
  336. save_config_params(&gateway);
  337. }
  338. /*
  339. * 函数名: void mmodbusRead(CONFIG_PARAMS * gateway)
  340. * 输入参数:gateway网关存储的配置参数
  341. * 输出参数:网关结构体指针
  342. * 返回值:无
  343. * 函数作用:根据存储的设备信息发送modbus信息返回值存储到gateway->device_read_data[i].data中
  344. * modbusRead读数据只考虑读16位寄存器和32位寄存器这两种情况,但对其返回值进行处理后返回值一律为float型4个字节存储在内部
  345. */
  346. void modbusRead(CONFIG_PARAMS *gateway)
  347. {
  348. for (int i = 0; i < gateway->device_read_data_num; i++)
  349. {
  350. delay_1ms(100);
  351. uint16_t data[gateway->device_read_data[i].registerLength/2];
  352. mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
  353. if (gateway->device_read_data[i].mdbFunctionCode == 0x03)
  354. {
  355. bool success = mmodbus_readHoldingRegisters16i(gateway->device_read_data[i].mdbSlave,
  356. gateway->device_read_data[i].mdbRegister,
  357. gateway->device_read_data[i].registerLength/2,
  358. data);
  359. if (success)
  360. {
  361. if (gateway->device_read_data[i].registerLength == 4)
  362. {
  363. uint32_t value = (uint32_t)data[0] << 16 | data[1];
  364. gateway->device_read_data[i].rxLen = 4;
  365. //增加小数点为0则gateway->device_read_data[i].data内存储为整形数据
  366. if(gateway->device_read_data[i].decimalPoint!=0) //小数点不为0的清空
  367. {
  368. float convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
  369. memcpy(gateway->device_read_data[i].data, &convertedValue, 4);
  370. }
  371. else if(gateway->device_read_data[i].decimalPoint==0) //小数点为0
  372. {
  373. gateway->device_read_data[i].data[0]=value;
  374. gateway->device_read_data[i].data[1]=value<<8;
  375. gateway->device_read_data[i].data[2]=value<<16;
  376. gateway->device_read_data[i].data[3]=value<<24;
  377. }
  378. }
  379. else if (gateway->device_read_data[i].registerLength == 2)
  380. {
  381. uint32_t value = data[0];
  382. gateway->device_read_data[i].rxLen = 4;
  383. if(gateway->device_read_data[i].decimalPoint!=0) //小数点不为0的清空
  384. {
  385. float convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
  386. memcpy(gateway->device_read_data[i].data, &convertedValue, 4);
  387. }
  388. else if(gateway->device_read_data[i].decimalPoint==0) //小数点为0
  389. {
  390. gateway->device_read_data[i].data[0]=value;
  391. gateway->device_read_data[i].data[1]=value<<8;
  392. gateway->device_read_data[i].data[2]=value<<16;
  393. gateway->device_read_data[i].data[3]=value<<24;
  394. }
  395. }
  396. }
  397. else
  398. {
  399. gateway->device_read_data[i].rxLen = 0;
  400. }
  401. }
  402. else if (gateway->device_read_data[i].mdbFunctionCode == 0x01)
  403. {
  404. uint8_t data[2];
  405. mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
  406. bool success = mmodbus_readCoils(gateway->device_read_data[i].mdbSlave,
  407. gateway->device_read_data[i].mdbRegister,
  408. gateway->device_read_data[i].registerLength,
  409. data);
  410. if (success)
  411. {
  412. uint32_t value = (uint32_t)data[0] << 8 | data[1];
  413. gateway->device_read_data[i].rxLen = 4;
  414. }
  415. else
  416. {
  417. gateway->device_read_data[i].rxLen = 0;
  418. }
  419. }
  420. task_fwdgt_reload();
  421. }
  422. }
  423. /*
  424. * 函数名:void parseMQTTData(CONFIG_PARAMS *gateway)
  425. * 输入参数:device存储的各类产品信息
  426. * 输出参数:无
  427. * 返回值:无
  428. * 函数作用:从环形缓冲区中一个个把json信息读出,与存储的gateway内的子设备信息匹配后将对应指令匹配执行并返回相应的值
  429. * 查询逻辑现在有两套数组read数组和write数组,当接收中断产生时先判断是进行读还是写、之后在查询此网关支持的协议MODBUS还是
  430. * 645,后根据协议去不同数组查询不同的本地存储信息、组装发送给子设备,然后根据查询的值进行采集上传数据
  431. */
  432. void parseMQTTData(CONFIG_PARAMS *gateway)
  433. {
  434. while (UART0_RX_MQTT_SUB_STAT == 1)
  435. {
  436. UART0_RX_MQTT_SUB_STAT = 0;
  437. char payload_out[200];
  438. char mqtt_publish[200];
  439. char json[128];
  440. while (MQTT_BUFFER_READ(json))
  441. {
  442. LogPrint(LOG_INFO, __func__, __LINE__, "Received JSON: %s", json);
  443. cJSON *mqtt_sub_json = cJSON_Parse(json);
  444. if (mqtt_sub_json != NULL)
  445. {
  446. uint8_t action1[1];
  447. uint8_t action;
  448. strcpy(action1, processStringData(mqtt_sub_json, "action"));
  449. // 解决字符串为
  450. if (action1[0] == '0')
  451. {
  452. action = 0;
  453. }
  454. else if (action1[0] == '1')
  455. {
  456. action = 1;
  457. }
  458. uint8_t identifier[20];
  459. strcpy(identifier, processStringData(mqtt_sub_json, "identifier"));
  460. uint8_t deviceId[20];
  461. strcpy(deviceId, processStringData(mqtt_sub_json, "deviceId"));
  462. uint16_t value = processIntData(mqtt_sub_json, "parameter");
  463. uint8_t messageId[10];
  464. strcpy(messageId, processStringData(mqtt_sub_json, "messageId"));
  465. // 判断其指令过来是读还是写
  466. if (action == MQTT_SUB_CMD_WRITE)
  467. {
  468. for (int i = 0; i <= gateway->device_write_data_num; i++)
  469. {
  470. if (strcmp(gateway->device_write_data[i].deviceId, deviceId) == 0)
  471. {
  472. if (strcmp(gateway->device_write_data[i].keyword, identifier) == 0) // 寻找到对应存储的地址
  473. {
  474. if (gateway->dataSource == MODBUS)
  475. {
  476. if (gateway->device_write_data[i].mdbFunctionCode == 0x05)
  477. {
  478. mmodbus_set16bitOrder(gateway->device_write_data[i].bigLittleFormat);
  479. bool success = mmodbus_writeCoil(gateway->device_write_data[i].mdbSlave,
  480. gateway->device_write_data[i].mdbRegister,
  481. (uint8_t)value);
  482. // 成功
  483. if (success)
  484. {
  485. sprintf((char *)payload_out,
  486. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
  487. action1,
  488. gateway->device_write_data[i].keyword,
  489. gateway->device_write_data[i].deviceId, messageId, success);
  490. }
  491. else
  492. sprintf((char *)payload_out,
  493. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
  494. action1,
  495. gateway->device_write_data[i].keyword,
  496. gateway->device_write_data[i].deviceId, messageId, success);
  497. }
  498. else if (gateway->device_write_data[i].mdbFunctionCode == 0x06)
  499. {
  500. mmodbus_set16bitOrder(gateway->device_write_data[i].bigLittleFormat);
  501. bool success = mmodbus_writeHoldingRegister16i(gateway->device_write_data[i].mdbSlave,
  502. gateway->device_write_data[i].mdbRegister,
  503. (uint16_t)value);
  504. if (success)
  505. {
  506. sprintf((char *)payload_out,
  507. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
  508. action1,
  509. gateway->device_write_data[i].keyword,
  510. gateway->device_write_data[i].deviceId, messageId, success);
  511. }
  512. else
  513. sprintf((char *)payload_out,
  514. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
  515. action1,
  516. gateway->device_write_data[i].keyword,
  517. gateway->device_write_data[i].deviceId, messageId, success);
  518. }
  519. else
  520. {
  521. // 考虑后续兼容其他自定义协议
  522. }
  523. }
  524. // DLT645暂时不支持写入操作
  525. else if (gateway->dataSource == DLT645)
  526. {
  527. LogPrint(LOG_ERROR, __func__, __LINE__, "DLT645 does not support write instructions");
  528. }
  529. }
  530. }
  531. else
  532. LogPrint(LOG_ERROR, __func__, __LINE__, "No child device information matched to settings");
  533. }
  534. }
  535. // 指令是来读某属性值的
  536. else if (action == MQTT_SUB_CMD_READ)
  537. {
  538. for (int i = 0; i <= gateway->device_read_data_num; i++)
  539. {
  540. if (strcmp(gateway->device_read_data[i].deviceId, deviceId) == 0)
  541. {
  542. if (strcmp(gateway->device_read_data[i].keyword, identifier) == 0) // 寻找到对应存储的地址
  543. {
  544. if (gateway->dataSource == MODBUS)
  545. {
  546. if (gateway->device_read_data[i].mdbFunctionCode == 0x01)
  547. {
  548. uint8_t data[2];
  549. mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
  550. bool success = mmodbus_readCoils(gateway->device_read_data[i].mdbSlave,
  551. gateway->device_read_data[i].mdbRegister,
  552. gateway->device_read_data[i].registerLength,
  553. data);
  554. uint8_t value1;
  555. if (success)
  556. {
  557. uint16_t value1 = (uint16_t)data[0] << 8 | data[1];
  558. if (value1 == 0xFF00)
  559. {
  560. value1 = 1;
  561. }
  562. else if (value1 == 0x0000)
  563. {
  564. value1 = 0;
  565. }
  566. // 读线圈成功的json
  567. sprintf((char *)payload_out,
  568. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"parameter\":%d}",
  569. action1,
  570. gateway->device_read_data[i].keyword,
  571. gateway->device_read_data[i].deviceId, messageId, success, value);
  572. }
  573. // 读线圈失败的json
  574. else
  575. sprintf((char *)payload_out,
  576. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
  577. action1,
  578. gateway->device_read_data[i].keyword,
  579. gateway->device_read_data[i].deviceId, messageId, success);
  580. }
  581. else if (gateway->device_read_data[i].mdbFunctionCode == 0x03)
  582. {
  583. uint16_t data[gateway->device_read_data[i].registerLength/2];
  584. mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
  585. bool success = mmodbus_readHoldingRegisters16i(gateway->device_read_data[i].mdbSlave,
  586. gateway->device_read_data[i].mdbRegister,
  587. gateway->device_read_data[i].registerLength/2,
  588. data);
  589. if (success)
  590. {
  591. float convertedValue;
  592. if (gateway->device_read_data[i].registerLength == 2)
  593. {
  594. uint16_t value = data[0];
  595. convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
  596. }
  597. else if (gateway->device_read_data[i].registerLength == 4)
  598. {
  599. uint32_t value = (uint32_t)data[0] << 16 | data[1];
  600. convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
  601. }
  602. // 读寄存器值成功的json
  603. sprintf((char *)payload_out,
  604. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":%.2f}",
  605. action1,
  606. gateway->device_read_data[i].keyword,
  607. gateway->device_read_data[i].deviceId, messageId, success, convertedValue);
  608. }
  609. else
  610. {
  611. // 读寄存器失败的json
  612. sprintf((char *)payload_out,
  613. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
  614. action1,
  615. gateway->device_read_data[i].keyword,
  616. gateway->device_read_data[i].deviceId, messageId, success);
  617. }
  618. }
  619. }
  620. else if (gateway->dataSource == DLT645)
  621. {
  622. float value;
  623. uint8_t minute, hour, day, month, year;
  624. uint8_t read_buf[10];
  625. gateway->device_read_data[i].rxLen = 0;
  626. memset(read_buf, 0, 10);
  627. memset(gateway->device_read_data[i].data, 0, 10); // 清空data内容
  628. dlt645_set_addr(&dlt645, gateway->device_read_data[i].deviceID645);
  629. int8_t rs = dlt645_read_data(&dlt645, gateway->device_read_data[i].dataType645, read_buf, DLT645_2007);
  630. if (rs != -1)
  631. {
  632. if (rs <= 4)
  633. {
  634. memcpy(&value, read_buf, 4);
  635. sprintf((char *)payload_out,
  636. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":%.2f}",
  637. action1,
  638. gateway->device_read_data[i].keyword,
  639. gateway->device_read_data[i].deviceId, messageId, 1, value);
  640. }
  641. else if (rs == 5)
  642. {
  643. memcpy(&value, gateway->device_read_data[i].data, 4);
  644. year = gateway->device_read_data[i].data[4];
  645. month = gateway->device_read_data[i].data[3];
  646. day = gateway->device_read_data[i].data[2];
  647. hour = gateway->device_read_data[i].data[1];
  648. minute = gateway->device_read_data[i].data[0];
  649. sprintf((char *)payload_out,
  650. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":\"%02X%02X%02X%02X%02X\"}",
  651. action1,
  652. gateway->device_read_data[i].keyword,
  653. gateway->device_read_data[i].deviceId, messageId, 1, year, month, day, hour, minute);
  654. }
  655. else if (rs > 5)
  656. {
  657. memcpy(&value, gateway->device_read_data[i].data, 4);
  658. year = gateway->device_read_data[i].data[8];
  659. month = gateway->device_read_data[i].data[7];
  660. day = gateway->device_read_data[i].data[6];
  661. hour = gateway->device_read_data[i].data[5];
  662. minute = gateway->device_read_data[i].data[4];
  663. sprintf((char *)payload_out,
  664. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":\"%02X%02X%02X%02X%02X%.2f\"}",
  665. action1,
  666. gateway->device_read_data[i].keyword,
  667. gateway->device_read_data[i].deviceId, messageId, 1, year, month, day, hour, minute, value);
  668. }
  669. }
  670. else
  671. {
  672. // dlt645读取失败的json组成
  673. sprintf((char *)payload_out,
  674. "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
  675. action1,
  676. gateway->device_read_data[i].keyword,
  677. gateway->device_read_data[i].deviceId, messageId, 0);
  678. }
  679. }
  680. }
  681. }
  682. }
  683. }
  684. // 上传对应的响应信息
  685. sprintf((char *)mqtt_publish, "AT+QMTPUBEX=0,0,0,0,\"%s\",%d\r\n", gateway->messageTopic, strlen(payload_out));
  686. EC800MSendCmd(mqtt_publish, strlen(mqtt_publish));
  687. WaitResponse("<", 1000);
  688. EC800MSendCmd(payload_out, strlen(payload_out));
  689. WaitResponse(RSP_OK, 1000);
  690. }
  691. cJSON_Delete(mqtt_sub_json);
  692. }
  693. }
  694. }
  695. /*
  696. * 函数名:void dlt645_read(CONFIG_PARAMS *gateway)
  697. * 输入参数:设备地址*address 数据标识 readCode
  698. * 输出参数:无
  699. * 返回值:无
  700. * 函数作用:读取645协议内部数据
  701. 备注:dlt645协议为网上下载,返回值为数据长度
  702. 现在要加读日期信息YYMMDDhhmm
  703. 对源代码改动不多的方法是通过返回的数据长度去做判断
  704. 当数据长度为2、3、4时此时 read_buf数据包内仅含采集到的浮点数数据、 把float值4个字节直接拷贝出即可
  705. 当数据长度为5时 read_buf数据包为日期数据 其中5个字节分别为YYMMDDhhmm直接拷贝出来
  706. 当数据长度大于5时 read_buf内既包含浮点数又包含日期时间 其中前4个字节为浮点数数据后五个字节为日期信息
  707. */
  708. void dlt645_read(CONFIG_PARAMS *gateway)
  709. {
  710. uint8_t read_buf[10];
  711. for (int i = 0; i < gateway->device_read_data_num; i++)
  712. {
  713. gateway->device_read_data[i].rxLen = 0;
  714. memset(read_buf, 0, 10);
  715. memset(gateway->device_read_data[i].data, 0, 10);
  716. dlt645_set_addr(&dlt645, gateway->device_read_data[i].deviceID645);
  717. int8_t rs;
  718. if(gateway->dataType645==DLT645_2007){
  719. rs = dlt645_read_data(&dlt645, gateway->device_read_data[i].dataType645, read_buf, DLT645_2007);
  720. }
  721. else {
  722. rs = dlt645_read_data(&dlt645, gateway->device_read_data[i].dataType645, read_buf, DLT645_1997);
  723. }
  724. if (rs != -1)
  725. {
  726. if (rs <= 4)
  727. {
  728. memcpy(gateway->device_read_data[i].data, read_buf, 4);
  729. gateway->device_read_data[i].rxLen = rs;
  730. }
  731. else if (rs == 5)
  732. {
  733. memcpy(gateway->device_read_data[i].data, read_buf, 5);
  734. gateway->device_read_data[i].rxLen = rs;
  735. }
  736. else if (rs > 5)
  737. {
  738. memcpy(gateway->device_read_data[i].data, read_buf, 9);
  739. gateway->device_read_data[i].rxLen = rs;
  740. }
  741. }
  742. else
  743. {
  744. gateway->device_read_data[i].rxLen = 0;
  745. }
  746. task_fwdgt_reload();
  747. }
  748. }
  749. // 模块下载download校验值
  750. static uint16_t checksum(const char *str, uint16_t len)
  751. {
  752. uint16_t sum = 0;
  753. uint8_t odd = 0;
  754. // 如果字符串长度为奇数,则将最后一个字符设置为高8位,低8位设置为0
  755. if (len % 2 == 1)
  756. {
  757. odd = 1;
  758. len--;
  759. }
  760. // 将每两个字符作为一个16位的数值进行异或操作
  761. for (uint16_t i = 0; i < len; i += 2)
  762. {
  763. sum ^= ((uint16_t)str[i] << 8) | (uint16_t)str[i + 1];
  764. }
  765. // 如果字符串长度为奇数,则还需要将最后一个字符与0xFF00异或
  766. if (odd)
  767. {
  768. sum ^= (uint16_t)str[len] << 8;
  769. }
  770. // 返回校验和
  771. return sum;
  772. }