expel.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. /***** (C) Copyright, Shenzhen SUNWIN Intelligent Co.,Ltd. ******source file****
  2. * File name : expel.cpp
  3. * Author : JinLiang Yang
  4. * Brief :
  5. ********************************************************************************
  6. * modify
  7. * Version Date Author Described
  8. * V2.00 2021/04/8 ShengYin Li Created
  9. *******************************************************************************/
  10. #include "expel.h"
  11. #include "config.hpp"
  12. //device
  13. #include "deviceGasV1.h"
  14. #include "deviceGasV2.h"
  15. #include "deviceGasV3.h"
  16. #include "deviceUlt.h"
  17. #include "deviceBase.h"
  18. #include "devicePlayer.h"
  19. #include "Network/TcpClient.h"
  20. using namespace toolkit;
  21. class ExpelClient: public TcpClient {
  22. public:
  23. typedef std::shared_ptr<ExpelClient> Ptr;
  24. ExpelClient():TcpClient() {
  25. }
  26. ~ExpelClient(){
  27. }
  28. /**
  29. * @description: setDeviceControl
  30. * @param {shared_ptr<deviceBase>} DeviceControl
  31. * @return {*}
  32. */
  33. void setDeviceControl(std::shared_ptr<deviceBase> DeviceControl){
  34. this->deviceControl = DeviceControl;
  35. }
  36. /**
  37. * @description: setSendBuf
  38. * @param {Ptr} Buffer
  39. * @return {*}
  40. */
  41. void setSendBuf(const BufferRaw::Ptr Buffer){
  42. buffer = Buffer;
  43. }
  44. protected:
  45. virtual void onConnect(const SockException &ex) override{
  46. //连接结果事件
  47. if(buffer != nullptr) this->send(buffer);
  48. }
  49. virtual void onRecv(const Buffer::Ptr &pBuf) override{
  50. int msg = 0;
  51. if(this->deviceControl == nullptr) return;
  52. if(this->deviceControl->Consumer((uint8_t *)pBuf->data(), (int)pBuf->size(), msg)){
  53. if(config::getPtr()->debug) DebugL << "deviceId[" << deviceControl->getDeviceId() << "] Device response is succeed" << endl;
  54. if(config::getPtr()->debug) DebugL << "REV:" << Expel::bytesToHexString((uint8_t *)pBuf->data(), (int)pBuf->size()) << endl;
  55. std::string json;
  56. SendDevice sendDevice;
  57. time_t timestamp;
  58. NettyClientResultMsg<SendDevice> nettyClientResultMsg;
  59. deviceControl->BuildDeviceInfo(sendDevice);
  60. time(&timestamp);
  61. sendDevice.msgTime = ctime(&timestamp);
  62. std::string requestId;
  63. requestId = uuid::generate();
  64. nettyClientResultMsg.setRequestId(requestId);
  65. nettyClientResultMsg.setDataType(NettyClientCommandEnum().device_info);
  66. nettyClientResultMsg.setData(sendDevice);
  67. nettyClientResultMsg.objectToJson(json);
  68. NoticeCenter::Instance().emitEvent(NOTICE_DEVICEINFO, requestId ,json);
  69. }
  70. }
  71. virtual void onFlush() override{
  72. //发送阻塞后,缓存清空事件
  73. DebugL;
  74. }
  75. virtual void onErr(const SockException &ex) override{
  76. //断开连接事件,一般是EOF
  77. WarnL << ex.what();
  78. }
  79. virtual void onManager() override{
  80. }
  81. private:
  82. int _nTick = 0;
  83. std::shared_ptr<deviceBase> deviceControl = nullptr;
  84. BufferRaw::Ptr buffer = nullptr;
  85. };
  86. Expel::Expel(){
  87. }
  88. void Expel::Init()
  89. {
  90. }
  91. /**
  92. * @description: 获取Ptr
  93. * @return {*}
  94. */
  95. std::shared_ptr<Expel> Expel::getPtr(){
  96. static std::shared_ptr<Expel> m_Expel = nullptr;
  97. if(m_Expel == nullptr) m_Expel = std::shared_ptr<Expel>(new Expel);
  98. return m_Expel;
  99. }
  100. /**
  101. * @description:
  102. * @param {string} &commandCode
  103. * @return {*}
  104. */
  105. int32_t Expel::Controler(std::string commandCode){
  106. int code = atoi(commandCode.c_str());
  107. switch (code)
  108. {
  109. // 开启电源
  110. case 2:
  111. this->AllOpen();
  112. break;
  113. // 关闭电源
  114. case 3:
  115. this->AllClose();
  116. break;
  117. // 开炮
  118. case 4:
  119. this->AllFire();
  120. break;
  121. default:
  122. break;
  123. }
  124. return OK;
  125. }
  126. /**
  127. * @description:
  128. * @param {NettyServerResultMsg<RecDeviceCommand>} &nettyServerResultMsg
  129. * @param {ExpelDevice} expelDevice
  130. * @return {*}
  131. */
  132. void Expel::sendDeviceMsgCallback(NettyServerResultMsg<RecDeviceCommand> &nettyServerResultMsg, ExpelDevice expelDevice) {
  133. RecDeviceCommand recDeviceCommand;
  134. recDeviceCommand = nettyServerResultMsg.getData();
  135. std::string deviceId = to_string(recDeviceCommand.getDeviceId());
  136. int commandCode = atoi(recDeviceCommand.getCommandCode().c_str());
  137. //InfoL << "deviceId:" << recDeviceCommand.getDeviceId();
  138. switch (commandCode)
  139. {
  140. // 查询
  141. case 1:
  142. this->Status(expelDevice);
  143. break;
  144. // 开启电源
  145. case 2:
  146. this->Open(expelDevice);
  147. break;
  148. // 关闭电源
  149. case 3:
  150. this->Close(expelDevice);
  151. break;
  152. // 开炮
  153. case 4:
  154. this->Fire(expelDevice);
  155. break;
  156. default:
  157. break;
  158. }
  159. }
  160. Expel::~Expel() {
  161. InfoL << "Release Expel resources";
  162. }
  163. /**
  164. * @description: 获取控制器
  165. * @param {*}
  166. * @return {*}
  167. */
  168. std::shared_ptr<deviceBase> Expel::getControl(ExpelDevice& expelDevice){
  169. static std::shared_ptr<deviceBase> deviceControl = nullptr;
  170. switch (expelDevice.deviceType)
  171. {
  172. case DeviceGasV1:
  173. deviceControl = std::make_shared<deviceGasV1>();
  174. break;
  175. case DeviceGasV2:
  176. deviceControl = std::make_shared<deviceGasV2>();
  177. break;
  178. case DeviceUlt:
  179. deviceControl = std::make_shared<deviceUlt>();
  180. break;
  181. case DevicePlayer:
  182. deviceControl = std::make_shared<devicePlayer>();
  183. break;
  184. case DeviceGasV3:
  185. deviceControl = std::make_shared<deviceGasV3>();
  186. break;
  187. }
  188. // 设置token
  189. deviceControl->setDeviceToken((enum DeviceToken)expelDevice.deviceToken);
  190. deviceControl->setServerIp(expelDevice.ServerIp);
  191. deviceControl->setServerCname(expelDevice.ServerCname);
  192. deviceControl->setServerCpwd(expelDevice.ServerCpwd);
  193. return deviceControl;
  194. }
  195. /**
  196. * @description: 打开设备
  197. * @param {int} deivceId
  198. * @return {*}
  199. */
  200. int32_t Expel::Open(ExpelDevice& expelDevice){
  201. std::shared_ptr<deviceBase> deviceControl = nullptr;
  202. deviceControl = getControl(expelDevice);
  203. uint8_t data[1024];
  204. memset(data, 0, sizeof(data));
  205. int length = 0;
  206. std::string deviceId = expelDevice.DeviceId;
  207. deviceControl->setDeviceId(deviceId);
  208. if(config::getPtr()->debug) InfoL << "DeviceId:" << deviceId << ", deviceType:" << expelDevice.deviceType << endl;
  209. // 获取指令
  210. if(deviceControl != nullptr && deviceControl->Open(deviceId, data, length) == 0){
  211. return Control(deviceControl, expelDevice, data, length, 2);
  212. }
  213. return -1;
  214. }
  215. /**
  216. * @description: 关闭设备
  217. * @param {int} deivceId
  218. * @return {*}
  219. */
  220. int32_t Expel::Close(ExpelDevice& expelDevice){
  221. std::shared_ptr<deviceBase> deviceControl = nullptr;
  222. deviceControl = getControl(expelDevice);
  223. uint8_t data[1024];
  224. memset(data, 0, sizeof(data));
  225. int length = 0;
  226. std::string deviceId = expelDevice.DeviceId;
  227. if(config::getPtr()->debug) InfoL << "DeviceId:" << deviceId << ", deviceType:" << expelDevice.deviceType << endl;
  228. // 获取指令
  229. if(deviceControl != nullptr && deviceControl->Close(deviceId, data, length) == 0){
  230. return Control(deviceControl, expelDevice, data, length, 3);
  231. }
  232. return -1;
  233. }
  234. /**
  235. * @description: 开火
  236. * @param {int} deivceId
  237. * @return {*}
  238. */
  239. int32_t Expel::Fire(ExpelDevice& expelDevice){
  240. std::shared_ptr<deviceBase> deviceControl = nullptr;
  241. deviceControl = getControl(expelDevice);
  242. uint8_t data[1024];
  243. memset(data, 0, sizeof(data));
  244. int length = 0;
  245. std::string deviceId = expelDevice.DeviceId;
  246. if(config::getPtr()->debug) InfoL << "DeviceId:" << deviceId << ", deviceType:" << expelDevice.deviceType << endl;
  247. // 获取指令
  248. if(deviceControl != nullptr && deviceControl->Fire(deviceId, data, length) == 0){
  249. return Control(deviceControl, expelDevice, data, length, 4);
  250. }
  251. return -1;
  252. }
  253. /**
  254. * @description: 状态
  255. * @param {int} deviceId
  256. * @param {string&} json
  257. * @return {*}
  258. */
  259. int32_t Expel::Status(ExpelDevice& expelDevice){
  260. std::shared_ptr<deviceBase> deviceControl = nullptr;
  261. deviceControl = getControl(expelDevice);
  262. uint8_t data[1024];
  263. memset(data, 0, sizeof(data));
  264. int length = 0;
  265. std::string deviceId = expelDevice.DeviceId;
  266. if(config::getPtr()->debug) InfoL << "DeviceId:" << deviceId << ", deviceType:" << expelDevice.deviceType << endl;
  267. // 获取指令
  268. if(deviceControl != nullptr && deviceControl->Status(deviceId, data, length) == 0){
  269. return Control(deviceControl, expelDevice, data, length, 1);
  270. }
  271. return -1;
  272. }
  273. /**
  274. * @description: 数组转换为16进制字符串
  275. * @param {uint8_t*} bytes
  276. * @param {int} length
  277. * @return {*}
  278. */
  279. std::string Expel::bytesToHexString(const uint8_t* bytes,const int length)
  280. {
  281. if (bytes == NULL) {
  282. return "";
  283. }
  284. std::string buff;
  285. const int len = length;
  286. for (int j = 0; j < len; j++) {
  287. int high = bytes[j]/16, low = bytes[j]%16;
  288. buff += (high<10) ? ('0' + high) : ('a' + high - 10);
  289. buff += (low<10) ? ('0' + low) : ('a' + low - 10);
  290. buff += " ";
  291. }
  292. return buff;
  293. }
  294. /**
  295. * @description: control
  296. * @param {*}
  297. * @return {*}
  298. */
  299. int32_t Expel::Control(std::shared_ptr<deviceBase>& deviceControl, ExpelDevice& expelDevice, uint8_t* data, int& length, int type){
  300. static ExpelClient::Ptr client(new ExpelClient());
  301. std::lock_guard<mutex> gurad(m_mutex);
  302. deviceControl->setDeviceId(expelDevice.DeviceId);
  303. deviceControl->setControlType(type);
  304. if(deviceControl->getDevcieToken() == serial){
  305. CSerialPort ser;
  306. config::Ptr m_config = config::getPtr();
  307. if(m_config->debug) DebugL << "Serial control data:" << bytesToHexString(data, length) << endl;
  308. ser.init(m_config->comPort.c_str());
  309. ser.setBaudRate(deviceControl->getBaudRate());
  310. if(!ser.open()){
  311. ErrorL << "Open port falied!";
  312. return -1;
  313. }
  314. if(ser.writeData((const char*)data, length) != length){
  315. WarnL << "Control command failed" << endl;
  316. return -1;
  317. }
  318. this->SerialReceive(ser, deviceControl);
  319. ser.close();
  320. return 0;
  321. }else if(deviceControl->getDevcieToken() == http){
  322. if(expelDevice.ServerIp == ""){
  323. ErrorL << "The device IP address is empty" << endl;
  324. return -1;
  325. }
  326. httplib::Client cli(expelDevice.ServerIp, config::getPtr()->ExpelPort);
  327. std::string json;
  328. json = (char*)data;
  329. DebugL << "Http control data:" << json << endl;
  330. PlayerInquire playerInquire;
  331. if (auto res = cli.Post(playerInquire.getUrl().c_str(), json, "application/json")) {
  332. if (res->status == 200) {
  333. DebugL << res->body << endl;
  334. return 0;
  335. }else {
  336. WarnL << res->body << endl;
  337. return -1;
  338. }
  339. } else {
  340. auto err = res.error();
  341. ErrorL << "HTTP Service unavailable:" << err << endl;
  342. return -1;
  343. }
  344. }else if(deviceControl->getDevcieToken() == tcp){
  345. if(expelDevice.ServerIp == ""){
  346. ErrorL << "The device IP address is empty" << endl;
  347. return -1;
  348. }
  349. client->setDeviceControl(deviceControl);
  350. if(!client->alive()) client->startConnect(expelDevice.ServerIp, config::getPtr()->ExpelPort);
  351. if(config::getPtr()->debug) DebugL << "Serial control data:" << bytesToHexString(data, length) << endl;
  352. auto buf = BufferRaw::create();
  353. buf->assign((char*)data, length);
  354. client->setSendBuf(buf);
  355. if(client->alive()) client->send(buf);
  356. }
  357. else return -1;
  358. }
  359. /**
  360. * @description: 串口数据接收
  361. * @param {*}
  362. * @return {*}
  363. */
  364. bool Expel::SerialReceive(CSerialPort& ser, std::shared_ptr<deviceBase>& deviceControl){
  365. if(ser.isOpened()){
  366. Ticker ticker0;
  367. uint8_t buffer[1024];
  368. memset(buffer, 0, sizeof(buffer));
  369. config::Ptr m_config = config::getPtr();
  370. while (true)
  371. {
  372. if(ticker0.elapsedTime() >= 2000){
  373. WarnL << "deviceId[" << deviceControl->getDeviceId() << "] Control instruction timeout" << endl;
  374. break;
  375. }
  376. int len = ser.readAllData((char *)(buffer));
  377. if(len == 0) continue;
  378. int msg_id;
  379. if(deviceControl->Consumer(buffer, len, msg_id)){
  380. if(m_config->debug) DebugL << "deviceId[" << deviceControl->getDeviceId() << "] Device response is succeed" << endl;
  381. if(m_config->debug) DebugL << "REV:" << bytesToHexString(buffer, len) << endl;
  382. if(deviceControl->getStatusMsg(msg_id)){
  383. std::string json;
  384. SendDevice sendDevice;
  385. time_t timestamp;
  386. NettyClientResultMsg<SendDevice> nettyClientResultMsg;
  387. deviceControl->BuildDeviceInfo(sendDevice);
  388. time(&timestamp);
  389. sendDevice.msgTime = ctime(&timestamp);
  390. std::string requestId;
  391. requestId = uuid::generate();
  392. nettyClientResultMsg.setRequestId(requestId);
  393. nettyClientResultMsg.setDataType(NettyClientCommandEnum().device_info);
  394. nettyClientResultMsg.setData(sendDevice);
  395. nettyClientResultMsg.objectToJson(json);
  396. NoticeCenter::Instance().emitEvent(NOTICE_DEVICEINFO, requestId ,json);
  397. }
  398. break;
  399. }
  400. }
  401. }
  402. return true;
  403. }
  404. /**
  405. * @description: 全部打开
  406. * @param {*}
  407. * @return {*}
  408. */
  409. int32_t Expel::AllOpen(){
  410. if(!config::getPtr()->LowVersion){
  411. for (auto iter = m_deviceLists.begin(); iter != m_deviceLists.end(); iter++){
  412. this->Open(*iter);
  413. }
  414. }else{
  415. if(config::getPtr()->DeviceIds.empty()){
  416. return 0;
  417. }
  418. for(auto iter = config::getPtr()->DeviceIds.begin(); iter != config::getPtr()->DeviceIds.end(); iter++){
  419. ExpelDevice expelDevice;
  420. expelDevice.DeviceId = std::to_string(*iter);
  421. expelDevice.deviceType = (enum DeviceType)config::getPtr()->deviceType;
  422. if(expelDevice.deviceType == 4) expelDevice.deviceToken = tcp;
  423. else if(expelDevice.deviceType == 3) expelDevice.deviceToken = http;
  424. else expelDevice.deviceToken = serial;
  425. this->Open(expelDevice);
  426. }
  427. }
  428. return 0;
  429. }
  430. /**
  431. * @description:
  432. * @param {*}
  433. * @return {*}
  434. */
  435. int32_t Expel::AllClose(){
  436. if(!config::getPtr()->LowVersion){
  437. for (auto iter = m_deviceLists.begin(); iter != m_deviceLists.end(); iter++){
  438. this->Close(*iter);
  439. }
  440. }else{
  441. if(config::getPtr()->DeviceIds.empty()) return 0;
  442. for(auto iter = config::getPtr()->DeviceIds.begin(); iter != config::getPtr()->DeviceIds.end(); iter++){
  443. ExpelDevice expelDevice;
  444. expelDevice.DeviceId = std::to_string(*iter);
  445. expelDevice.deviceType = (enum DeviceType)config::getPtr()->deviceType;
  446. if(expelDevice.deviceType == 4) expelDevice.deviceToken = tcp;
  447. else if(expelDevice.deviceType == 3) expelDevice.deviceToken = http;
  448. else expelDevice.deviceToken = serial;
  449. this->Close(expelDevice);
  450. }
  451. }
  452. return 0;
  453. }
  454. /**
  455. * @description: 全部开炮
  456. * @param {*}
  457. * @return {*}
  458. */
  459. int32_t Expel::AllFire(){
  460. if(!config::getPtr()->LowVersion){
  461. for (auto iter = m_deviceLists.begin(); iter != m_deviceLists.end(); iter++){
  462. this->Fire(*iter);
  463. }
  464. }else{
  465. if(config::getPtr()->DeviceIds.empty()) return 0;
  466. for(auto iter = config::getPtr()->DeviceIds.begin(); iter != config::getPtr()->DeviceIds.end(); iter++){
  467. ExpelDevice expelDevice;
  468. expelDevice.DeviceId = std::to_string(*iter);
  469. expelDevice.deviceType = (enum DeviceType)config::getPtr()->deviceType;
  470. if(expelDevice.deviceType == 4) expelDevice.deviceToken = tcp;
  471. else if(expelDevice.deviceType == 3) expelDevice.deviceToken = http;
  472. else expelDevice.deviceToken = serial;
  473. this->Fire(expelDevice);
  474. }
  475. }
  476. return 0;
  477. }
  478. /**
  479. * @description: 获取设备列表
  480. * @param {*}
  481. * @return {*}
  482. */
  483. int32_t Expel::UpdateDeviceList(vector<vector<std::string>>& datas){
  484. if(datas.empty()) {
  485. this->m_deviceLists.clear();
  486. return 0;
  487. }
  488. this->m_deviceLists.clear();
  489. for(auto &line: datas){
  490. ExpelDevice expelDevice;
  491. expelDevice.DeviceId = line[0];
  492. expelDevice.deviceToken =(enum DeviceToken)atoi(line[1].c_str());
  493. expelDevice.deviceType = (enum DeviceType)atoi(line[2].c_str());
  494. expelDevice.ServerIp = line[3];
  495. expelDevice.ServerCname = line[4];
  496. expelDevice.ServerCpwd = line[5];
  497. this->m_deviceLists.push_back(expelDevice);
  498. }
  499. return 0;
  500. }
  501. /**
  502. * @description: 获取驱鸟设备数量
  503. * @param {*}
  504. * @return {int32_t}
  505. */
  506. int32_t Expel::getExpelSize(){
  507. if(!config::getPtr()->LowVersion){
  508. return m_deviceLists.size();
  509. }else{
  510. return config::getPtr()->DeviceIds.size();
  511. }
  512. }
  513. /******** (C) Copyright, Shenzhen SUNWIN Intelligent Co.,Ltd. ******** End *****/