AirProtocol.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. 
  2. #include "AirProtocol.hpp"
  3. #include <cmn/proto/params.h>
  4. #include <cmn/proto/ui/option_list.h>
  5. #include <megopp/util/scope_cleanup.h>
  6. #include <cmn/plugin_framework/plugin.h>
  7. #include <Cmnpp/Proto/Operate.h>
  8. #include <Cmnpp/Proto/Point.h>
  9. #include "cmn/proto/log.h"
  10. #include <Cmnpp/Link.h>
  11. #include "DataHelper.hpp"
  12. void AirProtocol::parameters_get(cmnproto_params* _param)
  13. {
  14. cmnproto_params_set(
  15. _param,
  16. u8"HISENSEAIRV301",
  17. CMNPROTO_VER,
  18. COMM_MAKE_VER_NUM(0, 0, 1),
  19. cmnenum_duplex_half, // 半双工驱动方式
  20. cmnenum_data_process_collect, // 该协议是采集协议
  21. cmnenum_linkmode_serial, //< 指定协议驱动的连接模式支持串口
  22. // cmnenum_linkmode_network,
  23. cmnenum_linktype_none,
  24. cmnenum_linkquantity_singleline_singlelink, // 该协议只使用单通道单链接
  25. u8"HISENSEAIRV301"
  26. );
  27. // 设置参数
  28. auto optList = cmnproto_ui_optlist__create_by_str_v2(
  29. u8"PROTO_VERSION",
  30. u8"协议版本号",
  31. u8"协议版本号",
  32. u8"1");
  33. MEGOPP_UTIL__ON_SCOPE_CLEANUP([&optList] { cmnproto_ui_optlist_destruct(&optList); });
  34. cmnproto_params_lineopt_append(
  35. _param,
  36. u8"通信参数",
  37. optList
  38. );
  39. }
  40. cmnec_t AirProtocol::initialize_cb(cmnproto_handle _handle)
  41. {
  42. handle_ = _handle;
  43. handle_.timerStart(10);
  44. cmnerrno_t ret = 0;
  45. ret = handle_.lineGet(line_);
  46. eqpt_ = handle_.eqptGet();
  47. if (ret) {
  48. return CMNERRNO_ERROR;
  49. }
  50. ver_ = eqpt_.getOptionString("PROTO_VERSION");
  51. auto ver = atoi(ver_.c_str());
  52. // region 设置查询命令
  53. current_cmd_index_ = 0;
  54. // 遥测
  55. queryCmd_.push_back(0x42);
  56. // 遥信
  57. queryCmd_.push_back(0x43);
  58. // 告警
  59. queryCmd_.push_back(0x44);
  60. // 告警
  61. queryCmd_.push_back(0x51);
  62. // 33版本之后的
  63. if(ver >= 33 )
  64. { // 系统参数
  65. queryCmd_.push_back(0xC2);
  66. // 系统参数
  67. queryCmd_.push_back(0x47);
  68. }
  69. // endregion 设置查询命令
  70. return 0;
  71. }
  72. cmnec_t AirProtocol::terminate_cb()
  73. {
  74. handle_ = nullptr;
  75. line_ = nullptr;
  76. eqpt_.reset();
  77. memset(buffer,0, sizeof(buffer));
  78. current_cmd_index_ = -1;
  79. return 0;
  80. }
  81. cmnec_t AirProtocol::link_new_cb(cmnlink_ref _link)
  82. {
  83. // eqpt_.onlineStateChange(cmnenum_ostate_online);
  84. currentLink_ = _link;
  85. return 0;
  86. }
  87. cmnec_t AirProtocol::link_del_cb(cmnlink_ref _link)
  88. {
  89. if (currentLink_ == _link)
  90. currentLink_.reset();
  91. // eqpt_.onlineStateChange(cmnenum_ostate_offline);
  92. return 0;
  93. }
  94. cmnec_t AirProtocol::line_change_cb()
  95. {
  96. ver_ = eqpt_.getOptionString("PROTO_VERSION");
  97. return 0;
  98. }
  99. cmnec_t AirProtocol::process_cb()
  100. {
  101. // auto readCode = currBlock_.readCode();
  102. // auto dataAddr = currBlock_.addr();
  103. current_cmd_index_++;
  104. current_cmd_index_ = current_cmd_index_ %queryCmd_.size();
  105. const uint8_t queryCmd = queryCmd_.at(current_cmd_index_);
  106. cmnproto_log_debug(handle_.native(), "当前命令码: %02X,序号:%d", queryCmd, current_cmd_index_);
  107. // 获取通道版本号
  108. if(queryCmd == 0x42)
  109. {
  110. this->pack_yc_data();
  111. }
  112. else if(queryCmd == 0x43)
  113. {
  114. this->pack_yx_data();
  115. }
  116. else if(queryCmd == 0x44)
  117. {
  118. this->pack_alarm_data();
  119. }
  120. else if (queryCmd == 0x51)
  121. {
  122. this->pack_product_data();
  123. }
  124. else if (queryCmd == 0x47)
  125. {
  126. this->pack_query_data();
  127. }
  128. else if (queryCmd == 0xC2)
  129. {
  130. this->pack_yc1_data();
  131. }
  132. return CMNERRNO_OK;
  133. }
  134. void AirProtocol::pack_yc_data()
  135. {
  136. uint8_t data[1];
  137. // 打包并发送
  138. this->pack_data(data, 0, 0x60, 0x42);
  139. }
  140. void AirProtocol::unpack_yc_data( uint8_t* buf)
  141. {
  142. Cmnpp::Proto::ValueChange vchange;
  143. // 获取所有的通讯块
  144. const auto blockList = eqpt_.blockList();
  145. // 获取第一个通讯块
  146. const auto block = blockList.at(0);
  147. for(size_t i = 0; i < block.itemSize(); i++)
  148. {
  149. auto item = block.itemAt(i);
  150. if (!item)
  151. {
  152. continue;
  153. }
  154. if (item.addr() >= 100)
  155. {
  156. continue;
  157. }
  158. auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
  159. if (!p)
  160. {
  161. continue;
  162. }
  163. const int addr = item.addr();
  164. ret_value r_value;
  165. parse_value(item, buf, addr, r_value);
  166. if (r_value.type == 0) {
  167. vchange.append(p, r_value.double_value);
  168. }
  169. else {
  170. vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
  171. }
  172. //changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
  173. }
  174. update_changes(vchange);
  175. }
  176. void AirProtocol::pack_yc1_data()
  177. {
  178. uint8_t data[1];
  179. // 打包并发送
  180. this->pack_data(data, 0, 0x60, 0xC2);
  181. }
  182. void AirProtocol::unpack_yc1_data(uint8_t* buf)
  183. {
  184. Cmnpp::Proto::ValueChange vchange;
  185. // 获取所有的通讯块
  186. const auto blockList = eqpt_.blockList();
  187. // 获取第一个通讯块
  188. const auto block = blockList.at(0);
  189. for (size_t i = 0; i < block.itemSize(); i++)
  190. {
  191. auto item = block.itemAt(i);
  192. if (!item)
  193. {
  194. continue;
  195. }
  196. if (item.addr() < 100 || item.addr() >= 1000)
  197. {
  198. continue;
  199. }
  200. auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
  201. if (!p)
  202. {
  203. continue;
  204. }
  205. const int addr = item.addr() % 100;
  206. ret_value r_value;
  207. parse_value(item, buf, addr, r_value);
  208. if (r_value.type == 0) {
  209. vchange.append(p, r_value.double_value);
  210. }
  211. else {
  212. vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
  213. }
  214. // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
  215. }
  216. update_changes(vchange);
  217. }
  218. void AirProtocol::pack_query_data()
  219. {
  220. uint8_t data[1];
  221. // 打包并发送
  222. this->pack_data(data, 0, 0x60, 0x47);
  223. }
  224. void AirProtocol::unpack_query_data(uint8_t* buf)
  225. {
  226. Cmnpp::Proto::ValueChange vchange;
  227. // 获取所有的通讯块
  228. const auto blockList = eqpt_.blockList();
  229. // 获取第一个通讯块
  230. const auto block = blockList.at(3);
  231. for (size_t i = 0; i < block.itemSize(); i++)
  232. {
  233. auto item = block.itemAt(i);
  234. if (!item)
  235. {
  236. continue;
  237. }
  238. auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
  239. if (!p)
  240. {
  241. continue;
  242. }
  243. const int addr = item.addr();
  244. ret_value r_value;
  245. parse_value(item, buf, addr, r_value);
  246. if (r_value.type == 0) {
  247. vchange.append(p, r_value.double_value);
  248. }
  249. else {
  250. vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
  251. }
  252. // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
  253. }
  254. update_changes(vchange);
  255. }
  256. void AirProtocol::pack_yx_data()
  257. {
  258. uint8_t data[1];
  259. // 打包并发送
  260. this->pack_data(data, 0, 0x60, 0x43);
  261. }
  262. void AirProtocol::unpack_yx_data(uint8_t* buf)
  263. {
  264. Cmnpp::Proto::ValueChange vchange;
  265. // 获取所有的通讯块
  266. const auto blockList = eqpt_.blockList();
  267. // 获取第一个通讯块
  268. const auto block = blockList.at(1);
  269. for(size_t i = 0; i < block.itemSize(); i++)
  270. {
  271. auto item = block.itemAt(i);
  272. if (!item)
  273. {
  274. continue;
  275. }
  276. if(item.addr() >= 100)
  277. {
  278. continue;
  279. }
  280. auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
  281. if (!p)
  282. {
  283. continue;
  284. }
  285. const int addr = item.addr();
  286. ret_value r_value;
  287. parse_value(item, buf, addr, r_value);
  288. if (r_value.type == 0) {
  289. vchange.append(p, r_value.double_value);
  290. }
  291. else {
  292. vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
  293. }
  294. // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
  295. }
  296. this->update_changes(vchange);
  297. }
  298. void AirProtocol::pack_yk_data(const uint8_t ctrl_code)
  299. {
  300. uint8_t data[1];
  301. data[0] = ctrl_code;
  302. this->pack_data(data, 1, 0x60, 0x45);
  303. }
  304. void AirProtocol::unpack_yk_data(const uint8_t* buf)
  305. {
  306. frameMsg_ = handle_.createFrameMsg(eqpt_);
  307. frameMsg_.append(cmnproto_level_enum_info, 0, 0,
  308. u8"控制开关响应:%d", buf[7]);
  309. handle_.pushRecv(currentLink_, eqpt_, frameMsg_, buf_);
  310. }
  311. void AirProtocol::pack_alarm_data()
  312. {
  313. uint8_t data[1];
  314. this->pack_data(data, 0, 0x60, 0x44);
  315. }
  316. void AirProtocol::unpack_alarm_data(uint8_t* buf)
  317. {
  318. Cmnpp::Proto::ValueChange vchange;
  319. // 获取所有的通讯块
  320. const auto blockList = eqpt_.blockList();
  321. // 获取第一个通讯块
  322. const auto block = blockList.at(1);
  323. for(size_t i = 0; i < block.itemSize(); i++)
  324. {
  325. auto item = block.itemAt(i);
  326. if (!item)
  327. {
  328. continue;
  329. }
  330. if(item.addr() < 100 || item.addr() >= 1000)
  331. {
  332. continue;
  333. }
  334. auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
  335. if (!p)
  336. {
  337. continue;
  338. }
  339. const int addr = item.addr()%100;
  340. ret_value r_value;
  341. parse_value(item, buf, addr, r_value);
  342. if (r_value.type == 0) {
  343. vchange.append(p, r_value.double_value);
  344. }
  345. else {
  346. vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
  347. }
  348. // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
  349. }
  350. update_changes(vchange);
  351. }
  352. void AirProtocol::pack_product_data()
  353. {
  354. uint8_t data[1];
  355. this->pack_data(data, 0, 0x60, 0x51);
  356. }
  357. void AirProtocol::unpack_product_data(uint8_t* buf)
  358. {
  359. Cmnpp::Proto::ValueChange vchange;
  360. // 获取所有的通讯块
  361. const auto blockList = eqpt_.blockList();
  362. // 获取第一个通讯块
  363. const auto block = blockList.at(3);
  364. for (size_t i = 0; i < block.itemSize(); i++)
  365. {
  366. auto item = block.itemAt(i);
  367. if (!item)
  368. {
  369. continue;
  370. }
  371. auto p = item.relatedPoint().release<Cmnpp::Proto::Point>();
  372. if (!p)
  373. {
  374. continue;
  375. }
  376. const int addr = item.addr();
  377. ret_value r_value;
  378. parse_value(item, buf, addr, r_value);
  379. if (r_value.type == 0) {
  380. vchange.append(p, r_value.double_value);
  381. }
  382. else {
  383. vchange.append(p, mm_from(r_value.str_value, r_value.str_len));
  384. }
  385. // changes.emplace_back(cmnpoint_vchange_init_v(p.native(), sizeof(cmnpoint_vchange), value));
  386. }
  387. update_changes(vchange);
  388. }
  389. cmnec_t AirProtocol::operate_cb(cmnproto_operate_ref_const _oper)
  390. {
  391. // 操作请求
  392. const auto op = Cmnpp::Proto::OperateRef::Ref(_oper);
  393. switch (op.type())
  394. {
  395. case cmnenum_operate_type_remote_ctrl_exec:
  396. {
  397. this->pack_yk_data(static_cast<uint8_t>(op.value()));
  398. }
  399. default:
  400. break;
  401. }
  402. // 操作响应
  403. Cmnpp::Proto::OperateReply(op, 0, u8"操作成功");
  404. return 1;
  405. }
  406. cmnec_t AirProtocol::parse_cb()
  407. {
  408. cmnerrno_t ret = 0;
  409. // frameMsg_ = handle_.createFrameMsg(eqpt_);
  410. // frameMsg_.append(cmnproto_level_enum_info, 0, 0, u8"该报文长度为 %d 字节", static_cast<int>(buf_.size()));
  411. // MEGOPP_UTIL__ON_SCOPE_CLEANUP([this] { handle_.pushRecv(currentLink_, eqpt_, frameMsg_, buf_); });
  412. uint8_t index = 1;
  413. // 版本号
  414. uint8_t ver = DataHelper::read_uint8_ascii(buffer, index);
  415. // 地址
  416. uint8_t add = DataHelper::read_uint8_ascii(buffer, index);
  417. // cid1
  418. uint8_t cid1 = DataHelper::read_uint8_ascii(buffer, index);
  419. // cid2
  420. uint8_t cid2 = DataHelper::read_uint8_ascii(buffer, index);
  421. // 长度
  422. uint8_t len_buf[2];
  423. DataHelper::buffer_from_ascii_uint8(len_buf, buffer +index, 4);
  424. int lenID = DataHelper::get_len(len_buf);
  425. auto code = queryCmd_.at(current_cmd_index_);
  426. index += 4;
  427. // 读取数据
  428. // 遥测
  429. if (code == 0x42 )
  430. {
  431. this->unpack_yc_data(buffer + index);
  432. }
  433. // 遥信
  434. else if(code == 0x43)
  435. {
  436. this->unpack_yx_data(buffer + index);
  437. }
  438. else if(code == 0x44)
  439. {
  440. this->unpack_alarm_data(buffer + index);
  441. }
  442. else if(code == 0x45)
  443. {
  444. this->unpack_yk_data(buffer + index);
  445. }
  446. else if (code == 0x51)
  447. {
  448. this->unpack_product_data(buffer + index);
  449. }
  450. else if (code == 0xC2) {
  451. this->unpack_yc1_data(buffer + index);
  452. }
  453. else if (code == 0x47) {
  454. this->unpack_query_data(buffer + index);
  455. }
  456. else
  457. {
  458. frameMsg_.append(cmnproto_level_enum_error, 0, 0,
  459. u8"未知报文类型:%d", code);
  460. ret = CMNERRNO_ERROR;
  461. }
  462. return 0;
  463. }
  464. comm_integer_t AirProtocol::read_cb(cmnlink_ref _link)
  465. {
  466. auto linkCleanup = megopp::util::scope_cleanup__create([&] {
  467. currentLink_.readBufferClear();
  468. });
  469. memepp::variable_buffer buf_tmp_;
  470. currentLink_.readAll(buf_tmp_);
  471. // 追加到buf_
  472. buf_.append(buf_tmp_);
  473. buf_tmp_.clear();
  474. // 寻找EOI
  475. auto soiIndex = -1;
  476. auto eoiIndex = -1;
  477. // cmnproto_log_debug(handle_.native(), "报文长度:%d", buf_.size());
  478. for (size_t i = 0; i < buf_.size(); ++i)
  479. {
  480. if(soiIndex == -1 && buf_.at(i) == 0x7E)
  481. {
  482. soiIndex = i;
  483. }
  484. if(eoiIndex == -1 && buf_.at(i) == 0x0D)
  485. {
  486. eoiIndex = i;
  487. break;
  488. }
  489. }
  490. if (soiIndex == -1 )
  491. {
  492. cmnproto_log_debug(handle_.native(), "寻找SOI失败,继续等待");
  493. return 0;
  494. }
  495. if (eoiIndex == -1)
  496. {
  497. cmnproto_log_debug(handle_.native(), "寻找EOI失败,继续等待");
  498. return 0;
  499. }
  500. const auto buff_size = eoiIndex-soiIndex+1;
  501. memset(buffer, 0, 255);
  502. memcpy(buffer, buf_.data() + soiIndex, buff_size);
  503. // 拷贝一份出来,用于输出日志
  504. const memepp::variable_buffer print_buf_(buffer, buff_size);
  505. // 移除已拷贝了,将剩余的往前移
  506. if(soiIndex < buf_.size()-1)
  507. {
  508. buf_.remove(0, eoiIndex + 1);
  509. }
  510. if(eoiIndex - soiIndex < 18)
  511. {
  512. cmnproto_log_debug(handle_.native(), "报文长度过短,正常报文应不小于18");
  513. auto msg = handle_.createFrameMsg(eqpt_, cmnproto_level_enum_warn, 0, 0, u8"报文长度过短,正常报文应不小于18");
  514. // 开发者需要自己把接收到的报文信息通过handle_发到报文查看功能
  515. handle_.pushRecv(currentLink_, eqpt_, msg, print_buf_);
  516. return -1;
  517. }
  518. // 校验码
  519. uint8_t checksum[2];
  520. // 计算出来的校验码
  521. DataHelper::check_sum(buffer , 1, static_cast<int>(buff_size) - 6, checksum);
  522. // 当前校验码
  523. uint8_t rptCheckSum[2];
  524. DataHelper::buffer_from_ascii_uint8(rptCheckSum, buffer + (buff_size-5), 4);
  525. if (checksum[0] != rptCheckSum[0] || checksum[1] != rptCheckSum[1])
  526. {
  527. cmnproto_log_debug(handle_.native(), u8"校验码不正确,报文校验码:%02X%02X, 计算校验码:%02X%02X", rptCheckSum[0], rptCheckSum[1], checksum[0], checksum[1]);
  528. auto msg = handle_.createFrameMsg(eqpt_, cmnproto_level_enum_warn, 0, 0, u8"校验码不正确,报文校验码:%02X%02X, 计算校验码:%02X%02X", rptCheckSum[0], rptCheckSum[1], checksum[0], checksum[1]);
  529. handle_.pushRecv(currentLink_, eqpt_, msg, print_buf_);
  530. return 0;
  531. }
  532. auto msg = handle_.createFrameMsg(eqpt_, cmnproto_level_enum_info, 0, 0, u8"正确报文");
  533. // 开发者需要自己把接收到的报文信息通过handle_发到报文查看功能
  534. handle_.pushRecv(currentLink_, eqpt_, msg, print_buf_);
  535. // 拷贝到正确的报文缓存中
  536. linkCleanup.cancel();
  537. // 返回报文长度则回调parse_cb(),返回0则不回调parse_cb()
  538. return buff_size;
  539. }
  540. int AirProtocol::pack_data(uint8_t data[], const int data_len, const uint8_t cid1, const uint8_t cid2)
  541. {
  542. uint8_t index = 0;
  543. uint8_t buf[255];
  544. // SOI
  545. buf[index++] = 0x7E;
  546. auto ver = atoi(line_.getOptionString("PROTO_VERSION").c_str());
  547. // VER
  548. buf[index++] = 0x30 + (ver/10);
  549. buf[index++] = 0x30 + (ver%10);
  550. //DataHelper::buffer_copy_uint8_ascii(buf, 0x00, index) ;
  551. // 地址
  552. DataHelper::buffer_copy_uint8_ascii(buf, static_cast<uint8_t>(eqpt_.addr()), index) ;
  553. // CID1
  554. DataHelper::buffer_copy_uint8_ascii(buf, cid1, index);
  555. // CID2
  556. DataHelper::buffer_copy_uint8_ascii(buf, cid2, index);
  557. // 数据长度
  558. uint8_t len[2];
  559. DataHelper::generate_len(data_len, len);
  560. DataHelper::buffer_copy_uint8_ascii(buf, len[0], index);
  561. DataHelper::buffer_copy_uint8_ascii(buf, len[1], index);
  562. // 写入数据区
  563. memcpy(buf + index, data, data_len);
  564. index += data_len;
  565. // 校验码
  566. uint8_t checksum[2];
  567. DataHelper::check_sum(buf, 1, static_cast<int>(index) - 1, checksum);
  568. DataHelper::buffer_copy_uint8_ascii(buf, checksum[0], index);
  569. DataHelper::buffer_copy_uint8_ascii(buf, checksum[1], index);
  570. buf[index++] = 0x0D;
  571. cmnproto_log_debug(handle_.native(), "准备发送命令: CID1:%02X,CID2:%02X,", cid1, cid2);
  572. return handle_.send(currentLink_, buf, index);
  573. }
  574. void AirProtocol::parse_value(Cmnpp::Template::BlockItem item, uint8_t* buf, int addr, ret_value &r_value)
  575. {
  576. const auto type = cmntmpblk_item_datatype(item.native());
  577. if (type == cmnenum_value_int8 || type == cmnenum_value_int16 || type == cmnenum_value_int32)
  578. {
  579. uint8_t data[4];
  580. DataHelper::buffer_from_ascii_uint8(data, buf + addr, item.dataLength());
  581. auto value = DataHelper::get_signed_int(data, static_cast<int>(item.dataLength() / 2));
  582. r_value.double_value = value * item.coefficient();
  583. if (queryCmd_[current_cmd_index_] == 0x47) {
  584. cmnproto_log_debug(handle_.native(), "命令类型: %02X, 内存地址: %d, 数据长度:%d, 值:%f", queryCmd_[current_cmd_index_], item.addr(), item.dataLength(), r_value.double_value);
  585. }
  586. }
  587. else if (type== cmnenum_value_uint8 || type == cmnenum_value_uint16 || type == cmnenum_value_uint32)
  588. {
  589. uint8_t data[4];
  590. DataHelper::buffer_from_ascii_uint8(data, buf + addr, item.dataLength());
  591. auto value = DataHelper::get_unsigned_int(data, static_cast<int>(item.dataLength()/2));
  592. r_value.double_value = value * item.coefficient();
  593. if (queryCmd_[current_cmd_index_] == 0x47) {
  594. cmnproto_log_debug(handle_.native(), "命令类型: %02X, 内存地址: %d, 数据长度:%d, 值:%f", queryCmd_[current_cmd_index_], item.addr(), item.dataLength(), r_value.double_value);
  595. }
  596. }
  597. else if (type == cmnenum_value_string)
  598. {
  599. uint8_t data[100];
  600. memcpy(r_value.str_value,buf + addr, item.dataLength());
  601. r_value.str_len = static_cast<int>(item.dataLength());
  602. r_value.type = 1;
  603. if (queryCmd_[current_cmd_index_] == 0x47) {
  604. cmnproto_log_debug(handle_.native(), "命令类型: %02X, 内存地址: %d, 数据长度:%d, 值:%s", queryCmd_[current_cmd_index_], item.addr(), item.dataLength(), r_value.str_value);
  605. }
  606. }
  607. }
  608. void AirProtocol::update_changes(Cmnpp::Proto::ValueChange vchange)
  609. {
  610. // 更新至存储
  611. if (vchange.size() > 0) {
  612. int ret = vchange.updates();
  613. cmnproto_log_debug(handle_.native(), "命令类型: %02X, 总共数据量:%d, 更新值数量:%d", queryCmd_[current_cmd_index_], vchange.size(), ret);
  614. }
  615. }
  616. // 该函数是插件的退出函数,该函数会被插件加载器调用
  617. CMN_PLUGIN_API int64_t cmnplugin_exit()
  618. {
  619. return CMNERRNO_OK;
  620. }
  621. // 该函数是插件的入口函数,该函数会被插件加载器调用
  622. CMN_PLUGIN_API int64_t cmnplugin_initialize(
  623. const cmnplugin_init_params* _params, rsize_t _structSize, cmnplugin_exit_func_t* _func)
  624. {
  625. Cmnpp::IProtocolRegistrar registrar(_params, _structSize);
  626. auto ret = registrar.initialize();
  627. if (ret < 0)
  628. return CMNERRNO_ERROR;
  629. ret = registrar.registerObject<AirProtocol>("HISENSEAIRV301");
  630. if (ret < 0)
  631. return CMNERRNO_ERROR;
  632. *_func = cmnplugin_exit;
  633. return 0;
  634. }