BikeControl.php 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715
  1. <?php
  2. ///**
  3. // * Created by PhpStorm.
  4. // * User: Mead
  5. // * Date: 2019/9/5
  6. // * Time: 9:36 PM
  7. // */
  8. //
  9. //namespace App\Handlers\Weikemu;
  10. //
  11. //
  12. //use GatewayClient\Gateway;
  13. //use Illuminate\Support\Facades\Redis;
  14. //
  15. //class BikeControl
  16. //{
  17. // private static $start = '42 44';
  18. //
  19. // private static $registerAddress = 'node1:2238';
  20. //
  21. // // 还车成功,请规范停车
  22. // const VIDEO_RETURN_BIKE = '01';
  23. //// 开锁成功
  24. // const VIDEO_OPEN_LOCK = '02';
  25. //// 请文明骑行规范停车
  26. // const VIDEO_CIVILIZATION = '03';
  27. //// 车辆已断电请回到服务区
  28. // const VIDEO_POWER_FAILURE = '04';
  29. //// 车辆已下线
  30. // const VIDEO_OFFLINE = '05';
  31. //// 非法移动
  32. // const VIDEO_ILLEGAL_MOVE = '06';
  33. //// 临停成功将持续计费
  34. // const VIDEO_FIND_BIKE = '07';
  35. //// 向着诗和远方我们继续出发吧
  36. // const VIDEO_KEEP_GOING = '08';
  37. //// 小喵在这里
  38. // const VIDEO_BIKE_HERE = '09';
  39. //// 靠近服务区边缘,服务区外将断电 10
  40. // const VIDEO_BATTERY_EDGE = '0A';
  41. //// 换电完成您辛苦了 11
  42. // const VIDEO_POWER_CHANGE = '0B';
  43. //// 您已出服务区请尽快骑回 12
  44. // const VIDEO_GO_BEYOND = '0C';
  45. //// 夜间出行注意安全 13
  46. // const VIDEO_NIGHT_SAFETY = '0D';
  47. //// 当前为禁停区禁止停车 14
  48. // const VIDEO_NO_STOPPING = '0E';
  49. // // 空 15
  50. //
  51. // // 小喵生病了试试别的车吧 16
  52. // const VIDEO_USE_OTHER = '10';
  53. //
  54. // //电量过低 17
  55. // const VIDEO_LOW_POWER = '11';
  56. // // 主人即将回来试试别的车吧 18
  57. // const VIDEO_OCCUPIED = '12';
  58. // //小猫被预约了试试别的车吧 19
  59. // const VIDEO_RESERVED = '13';
  60. // // (带告警音)请停止偷窃行为 20
  61. // const VIDEO_WARNING = '14';
  62. // // 您已进入禁停区 21
  63. // const VIDEO_NO_STOP_ZONE = '15';
  64. // // 车辆已报警请勿移动 22
  65. // const VIDEO_ALARMED = '16';
  66. // //请停止偷窃行为 23
  67. // const VIDEO_NO_STEALING = '17';
  68. // // 设备已绑定 24
  69. // const VIDEO_BOUND = '18';
  70. // // 小喵摔倒了
  71. // const VIDEO_FALL = '19';
  72. //
  73. // /**
  74. // * 播放语音
  75. // * @param $box_no
  76. // * @return bool
  77. // * User: Mead
  78. // */
  79. // public static function playVoice($box_no, $voice_no)
  80. // {
  81. // $cmd = "2A";
  82. //
  83. // $body = [
  84. // self::getMsgId(),
  85. // '01',
  86. // $voice_no,
  87. // 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
  88. // 'FF FF FF FF',
  89. // 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
  90. // 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
  91. // ];
  92. //
  93. // $send_msg = self::makeSendMsg($cmd, $body);
  94. //
  95. // return self::send($box_no, $send_msg);
  96. // }
  97. //
  98. // /**
  99. // * queryCmd 3.2.1 查询指令
  100. // *
  101. // * @param $box_no
  102. // * @return bool
  103. // * @author Fx
  104. // *
  105. // */
  106. // public static function queryCmd($box_no, $str2 = '00111101')
  107. // {
  108. // // echo 'queryCmd' . PHP_EOL;
  109. // $cmd = "2B";
  110. //
  111. //// $str2 = '00111101'; // 3d
  112. // $body = [
  113. // self::getMsgId(),
  114. // str_pad(base_convert($str2, 2, 16), 2, 0, STR_PAD_LEFT)
  115. // ];
  116. //
  117. // $send_msg = self::makeSendMsg($cmd, $body);
  118. //
  119. // // echo $send_msg . PHP_EOL;
  120. // return self::send($box_no, $send_msg);
  121. // }
  122. //
  123. // /**
  124. // * electricSwitchControl 电门控制
  125. // *
  126. // * @param $box_no
  127. // * @param $control 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
  128. // * @return bool
  129. // * @author Fx
  130. // *
  131. // */
  132. // public static function electricSwitchControl($box_no, $control = "01")
  133. // {
  134. //// echo 'kaiguansuo' . PHP_EOL;
  135. // $cmd = "2D";
  136. //
  137. // $body = [
  138. // self::getMsgId(),
  139. // $control,// 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
  140. // ];
  141. //
  142. // $send_msg = self::makeSendMsg($cmd, $body);
  143. //
  144. // return self::send($box_no, $send_msg);
  145. // }
  146. //
  147. // /**
  148. // * realLocation 3.2.2 实时位置上报参数设置
  149. // *
  150. // * @param $box_no
  151. // * @param string $control 01:实时追踪开启,00:实时追踪关闭
  152. // * @param int $interval 上报间隔 秒 量化值30
  153. // * @param int $continued 持续时长(1-43200) 分钟
  154. // * @return bool
  155. // * @author Fx
  156. // *
  157. // */
  158. // public static function realLocation($box_no, $control = "01", $interval = 1, $continued = 60)
  159. // {
  160. //// $box_no = '868626040174578';
  161. // $cmd = "23";
  162. //
  163. // $body = [
  164. // self::getMsgId(),
  165. // $control,// 1:实时追踪开启,0:实时追踪关闭
  166. // str_pad(base_convert($interval, 10, 16), 4, 0, STR_PAD_LEFT),//上报间隔
  167. // str_pad(base_convert($continued, 10, 16), 4, 0, STR_PAD_LEFT),//持续时长(1-43200)
  168. // ];
  169. //
  170. // $send_msg = self::makeSendMsg($cmd, $body);
  171. //
  172. //// var_dump($body);
  173. // return self::send($box_no, $send_msg);
  174. // }
  175. //
  176. // /**
  177. // * multipleConfigsSetting 3.2.3 综合配置参数设置
  178. // *
  179. // * @param $box_no
  180. // * @param $arr
  181. // * @return bool
  182. // * @author Fx
  183. // *
  184. // */
  185. // public static function multipleConfigsSetting($box_no, $arr)
  186. // {
  187. //
  188. //
  189. // $cmd = "2C";
  190. //// ['ip' => $ip,'port' => $port,'bluetooth_name' => $bluetooth_name,'bluetooth_token' => $bluetooth_token,
  191. //// 'is_auto_lock' => $is_auto_lock, 'auto_lock_time' => $auto_lock_time,
  192. //// 'is_displacement' => $is_displacement, 'displacement_radius' => $displacement_radius,
  193. //// 'is_shock' => $is_shock,
  194. //// 'is_temperature' => $is_temperature,'temperature' => $temperature,
  195. //// 'is_speeding' => $is_speeding,'speeding'=>$speeding,
  196. //// 'motion_position_sampling_interval'=>$motion_position_sampling_interval,
  197. //// 'motion_position_reporting_interval'=>$motion_position_reporting_interval,
  198. //// 'static_position_reporting_interval'=>$static_position_reporting_interval];
  199. // $ip = $arr['ip'];
  200. // $port = $arr['port'];
  201. // $bluetooth_name = $arr['bluetooth_name']; // 蓝牙名称
  202. // $bluetooth_token = $arr['bluetooth_token']; //蓝牙token
  203. // $is_auto_lock = $arr['is_auto_lock']; // 是否开启自动落锁1:自动落锁开启;0:关闭自动落锁
  204. // $auto_lock_time = str_pad(base_convert($arr['auto_lock_time'], 10, 2), 7, 0, STR_PAD_LEFT); // 自动落锁时长,量化单位1分钟
  205. //
  206. // $is_displacement = $arr['is_displacement']; // 位移告警开启设置1:位移告警开启;0: 位移告警关闭
  207. // $displacement_radius = str_pad(base_convert($arr['displacement_radius'], 10, 2), 7, 0, STR_PAD_LEFT); // 位移告警半径门限,取值范围0~126,量化单位10米
  208. //
  209. // $is_shock = $arr['is_shock'];//震动告警开启设置1:震动告警开启,0:震动告警关闭
  210. //
  211. // $is_temperature = $arr['is_temperature'];//温度告警开启设置。1:温度告警开启;0:温度告警关闭
  212. // $temperature = str_pad(base_convert($arr['temperature'], 10, 2), 7, 0, STR_PAD_LEFT); // 温度告警门限,取值范围0~126,
  213. //
  214. // $is_speeding = $arr['is_speeding']; // 超速告警开启设置。1:超速告警开启;0:超速告警关闭
  215. // $speeding = str_pad(base_convert($arr['speeding'] * 2, 10, 2), 7, 0, STR_PAD_LEFT); // 超速告警门限 量化单位2km/h,范围 0~126
  216. // $motion_position_sampling_interval = $arr['motion_position_sampling_interval']; // 运动状态,位置采样间隔设置(默认1秒)
  217. // $motion_position_reporting_interval = $arr['motion_position_reporting_interval']; // 运动状态,位置上报间隔设置
  218. // $static_position_reporting_interval = $arr['static_position_reporting_interval']; // 静止状态,位置上报间隔设置
  219. //
  220. //
  221. // $body = [
  222. // self::getMsgId(),
  223. // str_pad(base_convert($motion_position_sampling_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置采样间隔设置(默认1秒)
  224. // str_pad(base_convert($motion_position_reporting_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置上报间隔设置
  225. // str_pad(base_convert($static_position_reporting_interval, 10, 16), 4, 0, STR_PAD_LEFT),// 静止状态,位置上报间隔设置
  226. // str_pad(base_convert($displacement_radius . $is_displacement, 2, 16), 2, 0, STR_PAD_LEFT),// 位移告警
  227. // str_pad(base_convert('0000000' . $is_shock, 2, 16), 2, 0, STR_PAD_LEFT),// 震动告警
  228. // str_pad(base_convert($temperature . $is_temperature, 2, 16), 2, 0, STR_PAD_LEFT),// 温度告警
  229. // str_pad(base_convert($speeding . $is_speeding, 2, 16), 2, 0, STR_PAD_LEFT),// 超速告警
  230. // str_pad(base_convert($auto_lock_time . $is_auto_lock, 2, 16), 2, 0, STR_PAD_LEFT),// 自动落锁
  231. // str_pad(base_convert($port, 10, 16), 4, 0, STR_PAD_LEFT),// 自动落锁
  232. // str_pad(base_convert($ip, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
  233. // str_pad($bluetooth_name, 10, 0, STR_PAD_LEFT),
  234. // str_pad(base_convert($bluetooth_token, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
  235. // '00 00 00 00 00 00'
  236. // ];
  237. //
  238. // $send_msg = self::makeSendMsg($cmd, $body);
  239. //
  240. // return self::send($box_no, $send_msg);
  241. // }
  242. //
  243. // /**
  244. // * reboot 重启中控
  245. // *
  246. // * @param $box_no
  247. // * @param $reboot string 11:重启升级;01:重启不升级
  248. // * @param $ip string 重启升级地址(域名或IP地址)
  249. // * @param $port int 重启升级端口号
  250. // * @param $path string 重启升级路径
  251. // * @param $upFile string 重启升级文件名称
  252. // * @return bool
  253. // * @author Fx
  254. // *
  255. // */
  256. // public static function reboot($box_no, $reboot = "01", $ip, $port, $path, $upFile)
  257. // {
  258. //// $box_no = '868626040174578';
  259. // $cmd = "25";
  260. //// $reboot = '000000' . $reboot; // 11:重启升级;01:重启不升级
  261. //
  262. //
  263. // $body = [
  264. // self::getMsgId(),
  265. // self::str2Hex($reboot, 2, 8),
  266. // self::char2Hex($ip, 20),
  267. // self::str2Hex($port, 10, 8),
  268. // self::char2Hex($path, 20),
  269. // self::char2Hex($upFile, 20),
  270. // ];
  271. //
  272. // $send_msg = self::makeSendMsg($cmd, $body);
  273. //
  274. // return self::send($box_no, $send_msg);
  275. // }
  276. //
  277. // /**
  278. // * settingVoice 语音设置
  279. // *
  280. // * @param $box_no
  281. // * @param $voice_no
  282. // * @param $ip
  283. // * @param $port
  284. // * @param $path
  285. // * @param $upFile
  286. // * @return bool
  287. // * @author Fx
  288. // *
  289. // */
  290. // public static function settingVoice($box_no, $voice_no, $ip, $port, $path, $upFile)
  291. // {
  292. //
  293. // $cmd = "2A";
  294. //
  295. // $body = [
  296. // self::getMsgId(),
  297. // '00',
  298. // self::str2Hex($voice_no, 10, 2),
  299. // self::char2Hex($ip, 20),
  300. // self::str2Hex($port, 10, 8),
  301. // self::char2Hex($path, 20),
  302. // self::char2Hex($upFile, 20),
  303. // ];
  304. //
  305. // $send_msg = self::makeSendMsg($cmd, $body);
  306. //
  307. // return self::send($box_no, $send_msg);
  308. // }
  309. //
  310. // /**
  311. // * guardSwitch 3.2.7 防盗开关设置
  312. // *
  313. // * @param $box_no
  314. // * @param $control 00:关闭 01:开启
  315. // * @return bool
  316. // * @author Fx
  317. // *
  318. // */
  319. // public static function guardSwitch($box_no, $control)
  320. // {
  321. //// echo 'guard' . PHP_EOL;
  322. //
  323. // $cmd = "2E";
  324. //
  325. // $body = [
  326. // self::getMsgId(),
  327. // $control
  328. // ];
  329. //
  330. // $send_msg = self::makeSendMsg($cmd, $body);
  331. //
  332. // return self::send($box_no, $send_msg);
  333. // }
  334. //
  335. // /**
  336. // * batterySwitch 3.2.8 电池仓开关设置
  337. // *
  338. // * @param $box_no
  339. // * @return bool
  340. // * @author Fx
  341. // *
  342. // */
  343. // public static function batterySwitch($box_no)
  344. // {
  345. //// echo 'batterySwitch' . PHP_EOL;
  346. //
  347. // $cmd = "2F";
  348. //
  349. // $body = [
  350. // self::getMsgId(),
  351. // '01',
  352. // ];
  353. //
  354. // $send_msg = self::makeSendMsg($cmd, $body);
  355. //
  356. // return self::send($box_no, $send_msg);
  357. // }
  358. //
  359. // /**
  360. // * limitSpeed 限速
  361. // *
  362. // * @param $box_no
  363. // * @param $limit int 限速[%]
  364. // * @return bool
  365. // * @author Fx
  366. // *
  367. // */
  368. // public static function limitSpeed($box_no, $limit)
  369. // {
  370. //
  371. // $cmd = "30";
  372. //
  373. // $body = [
  374. // self::getMsgId(),
  375. // self::str2Hex($limit, 10, 2),// 限速[%]
  376. // ];
  377. //
  378. // $send_msg = self::makeSendMsg($cmd, $body);
  379. //
  380. // return self::send($box_no, $send_msg);
  381. // }
  382. //
  383. // /**
  384. // * undervoltageProtection 3.2.10 控制器欠压保护设置
  385. // *
  386. // * @param $box_no
  387. // * @param $limit int 控制器欠压保护值,量单位1mv
  388. // * @return bool
  389. // * @author Fx
  390. // *
  391. // */
  392. // public static function undervoltageProtection($box_no, $limit)
  393. // {
  394. //
  395. // $cmd = "31";
  396. //
  397. // $body = [
  398. // self::getMsgId(),
  399. // self::str2Hex($limit, 10, 4),// 限速[%]
  400. // ];
  401. //
  402. // $send_msg = self::makeSendMsg($cmd, $body);
  403. //
  404. // return self::send($box_no, $send_msg);
  405. // }
  406. //
  407. //
  408. // /**
  409. // * currentLimitingProtection 3.2.11 控制器限流保护设置
  410. // *
  411. // * @param $box_no
  412. // * @param $limit int 控制器限流保护值,量化单位1mA
  413. // * @return bool
  414. // * @author Fx
  415. // *
  416. // */
  417. // public static function currentLimitingProtection($box_no, $limit)
  418. // {
  419. //
  420. // $cmd = "32";
  421. //
  422. // $body = [
  423. // self::getMsgId(),
  424. // self::str2Hex($limit, 10, 4),//
  425. // ];
  426. //
  427. // $send_msg = self::makeSendMsg($cmd, $body);
  428. //
  429. // return self::send($box_no, $send_msg);
  430. // }
  431. //
  432. // /**
  433. // * slowReboot 3.2.12 控制器缓启动设置
  434. // *
  435. // * @param $box_no
  436. // * @param $control string 01,缓启动;00,快启动
  437. // * @return bool
  438. // * @author Fx
  439. // *
  440. // */
  441. // public static function slowReboot($box_no, $control)
  442. // {
  443. //
  444. // $cmd = "33";
  445. //
  446. // $body = [
  447. // self::getMsgId(),
  448. // $control,
  449. // ];
  450. //
  451. // $send_msg = self::makeSendMsg($cmd, $body);
  452. //
  453. // return self::send($box_no, $send_msg);
  454. // }
  455. //
  456. // /**
  457. // * lampSwitch 3.2.13 控制器大灯设置
  458. // *
  459. // * @param $box_no
  460. // * @param $control string 01,大灯开;00,大灯关
  461. // * @return bool
  462. // * @author Fx
  463. // *
  464. // */
  465. // public static function lampSwitch($box_no, $control)
  466. // {
  467. //
  468. // $cmd = "34";
  469. //
  470. // $body = [
  471. // self::getMsgId(),
  472. // $control,
  473. // ];
  474. //
  475. // $send_msg = self::makeSendMsg($cmd, $body);
  476. //
  477. // return self::send($box_no, $send_msg);
  478. // }
  479. //
  480. //
  481. // /**
  482. // * orderStatus
  483. // *
  484. // * @param $box_no
  485. // * @param $control string 01:接单开启;00:接单关闭
  486. // * @return bool
  487. // * @author Fx
  488. // *
  489. // */
  490. // public static function orderStatus($box_no, $control)
  491. // {
  492. // $cmd = "35";
  493. //
  494. // $body = [
  495. // self::getMsgId(),
  496. // $control,
  497. // ];
  498. //
  499. // $send_msg = self::makeSendMsg($cmd, $body);
  500. //
  501. // return self::send($box_no, $send_msg);
  502. // }
  503. //
  504. // /**
  505. // * nowBikeLocation 立即定位
  506. // *
  507. // * @param $box_no
  508. // * @return bool
  509. // * @author Fx
  510. // *
  511. // */
  512. // public static function nowBikeLocation($box_no)
  513. // {
  514. // //删除ridis位置缓存
  515. // self::delRedisCache($box_no, 'update_bike_location');
  516. // return self::queryCmd($box_no, '00000001');
  517. // }
  518. //
  519. //
  520. // /**
  521. // * openLock 开锁
  522. // *
  523. // * @param $box_no
  524. // * @return bool
  525. // * @author Fx
  526. // *
  527. // */
  528. // public static function openLock($box_no)
  529. // {
  530. // self::playVoice($box_no, self::VIDEO_OPEN_LOCK);
  531. // self::orderStatus($box_no, '01');
  532. // return self::electricSwitchControl($box_no, '01');
  533. // }
  534. //
  535. // /**
  536. // * closeLock 关锁 (设防)
  537. // *
  538. // * @param $box_no
  539. // * @return bool
  540. // * @author Fx
  541. // *
  542. // */
  543. // public static function closeLock($box_no)
  544. // {
  545. // self::playVoice($box_no, self::VIDEO_RETURN_BIKE);
  546. // self::orderStatus($box_no, '00');
  547. // return self::electricSwitchControl($box_no, '02');
  548. // }
  549. //
  550. // /**
  551. // * closeLock 临时关锁 (设防)
  552. // *
  553. // * @param $box_no
  554. // * @return bool
  555. // * @author Fx
  556. // *
  557. // */
  558. // public static function temporaryCloseLock($box_no)
  559. // {
  560. // self::playVoice($box_no, self::VIDEO_FIND_BIKE);
  561. // return self::electricSwitchControl($box_no, '02');
  562. // }
  563. //
  564. // /**
  565. // * temporaryOpnLock 临时开锁
  566. // *
  567. // * @param $box_no
  568. // * @return bool
  569. // * @author Fx
  570. // *
  571. // */
  572. // public static function temporaryOpnLock($box_no)
  573. // {
  574. // self::playVoice($box_no, self::VIDEO_KEEP_GOING);
  575. // return self::electricSwitchControl($box_no, '01');
  576. // }
  577. //
  578. // /**
  579. // * closeLockNoGuard 关锁 (不设防) 失能
  580. // *
  581. // * @param $box_no
  582. // * @return bool
  583. // * @author Fx
  584. // *
  585. // */
  586. // public static function outAreaLoseElectric($box_no)
  587. // {
  588. // self::playVoice($box_no, self::VIDEO_GO_BEYOND);
  589. // return self::electricSwitchControl($box_no, '00');
  590. // }
  591. //
  592. // /**
  593. // * outAreaGetElectric 开锁 获能
  594. // *
  595. // * @param $box_no
  596. // * @return bool
  597. // * @author Fx
  598. // *
  599. // */
  600. // public static function outAreaGetElectric($box_no)
  601. // {
  602. // self::playVoice($box_no, self::VIDEO_KEEP_GOING);
  603. // return self::electricSwitchControl($box_no, '01');
  604. // }
  605. //
  606. // public static function bellBike($box_no)
  607. // {
  608. // return self::playVoice($box_no, self::VIDEO_BIKE_HERE);
  609. // }
  610. //
  611. // /**
  612. // * 删除缓存
  613. // * @param $box_no
  614. // * @param $type
  615. // * User: Mead
  616. // */
  617. // public static function delRedisCache($box_no, $types)
  618. // {
  619. // $cacheNames = [];
  620. // if (is_array($types)) {
  621. // foreach ($types as $type) {
  622. // $cacheNames[] = "cache:min:{$type}:{$box_no}";
  623. // }
  624. // } else {
  625. // $cacheNames[] = "cache:min:{$types}:{$box_no}";
  626. // }
  627. // if (!count($cacheNames)) return false;
  628. // Redis::connection()->del($cacheNames);
  629. // }
  630. //
  631. //
  632. // /**
  633. // * 获取序号(msg_id)
  634. // * @return string
  635. // * Author: Mead
  636. // */
  637. // private static function getMsgId()
  638. // {
  639. // $msg_id = str_pad(dechex(rand(0, 65535)), 4, "0", STR_PAD_LEFT);
  640. // return $msg_id;
  641. // }
  642. //
  643. // /**
  644. // * str2Hex 其他进制转16进制
  645. // *
  646. // * @param $str string 需要转的数据
  647. // * @param $frombase int 需要转的进制
  648. // * @param $pad_length int 长度
  649. // * @return string
  650. // * @author Fx
  651. // *
  652. // */
  653. // private static function str2Hex($str, $frombase, $pad_length)
  654. // {
  655. // return str_pad(base_convert($str, $frombase, 16), $pad_length, 0, STR_PAD_LEFT);
  656. // }
  657. //
  658. // /**
  659. // * char2Hex char 转16进制
  660. // *
  661. // * @param $char
  662. // * @param $pad_length
  663. // * @return string
  664. // * @author Fx
  665. // *
  666. // */
  667. // private static function char2Hex($char, $pad_length)
  668. // {
  669. // return str_pad(bin2hex($char), $pad_length, 0, STR_PAD_LEFT);
  670. // }
  671. //
  672. // /**
  673. // * 发送数据
  674. // * @param $box_no
  675. // * @param $msg
  676. // * @return bool
  677. // * User: Mead
  678. // */
  679. // private static function send($box_no, $msg)
  680. // {
  681. // Gateway::$registerAddress = config('bike.bike_control_register_address');
  682. // if (Gateway::isUidOnline($box_no)) {
  683. // Gateway::sendToUid($box_no, '+NNMI,' . hex2bin(str_replace(' ', '', $msg . '0D0A')));
  684. // return true;
  685. // }
  686. // return false;
  687. // }
  688. //
  689. // /**
  690. // * 组装命令
  691. // * @param $cmd
  692. // * @param $msgID
  693. // * @return string
  694. // * User: Mead
  695. // */
  696. // private static function makeSendMsg($cmd, $body, $msg_id = false, $length = false)
  697. // {
  698. // if (is_array($body)) {
  699. // $body = self::arr2arr($body);
  700. // }
  701. // if (is_string($body)) {
  702. // $body = str_split($body, 2);
  703. // }
  704. //
  705. //
  706. // if ($length !== false) {
  707. // $length = str_pad($length, 4, '0', STR_PAD_LEFT);
  708. // } else {
  709. // $length = str_pad(dechex(count($body)), 4, '0', STR_PAD_LEFT);
  710. // }
  711. //
  712. // if ($msg_id === false) {
  713. // $msg_id = self::getMsgId();
  714. // }
  715. // $header = [
  716. // $cmd,
  717. // $msg_id,
  718. // '00',
  719. // $length
  720. // ];
  721. // $response = self::formatArr($header, $body);
  722. // $response[] = self::verification($response);
  723. //
  724. // return self::format(self::$start . implode('', $response));
  725. // }
  726. //
  727. // /**
  728. // * 校检
  729. // * @param $data
  730. // * @param $verification
  731. // * @return bool
  732. // * Author: Mead
  733. // */
  734. // protected static function verification($data)
  735. // {
  736. // $a = $b = 0;
  737. // for ($i = 0; $i < count($data); $i++) {
  738. // $a = $a + hexdec($data[$i]);
  739. // $b = $a + $b;
  740. // }
  741. // return str_pad(substr(dechex($a), -2), 2, 0, STR_PAD_LEFT) . str_pad(substr(dechex($b), -2), 2, 0, STR_PAD_LEFT);
  742. // }
  743. //
  744. // /**
  745. // * 格式数组
  746. // * @param $arr
  747. // * @return array
  748. // * User: Mead
  749. // */
  750. // private static function arr2arr($arr)
  751. // {
  752. // $arr = implode('', $arr);
  753. // return str_split(str_replace(' ', '', $arr), 2);
  754. // }
  755. //
  756. // /**
  757. // * 合并数组
  758. // * @return array
  759. // * User: Mead
  760. // */
  761. // private static function formatArr()
  762. // {
  763. // $args = func_get_args();
  764. // $arr = '';
  765. // foreach ($args as $arg) {
  766. // $arr .= implode('', $arg);
  767. // }
  768. // return str_split($arr, 2);
  769. // }
  770. //
  771. // /**
  772. // * 格式字符
  773. // * @param $str
  774. // * @return string
  775. // * User: Mead
  776. // */
  777. // private static function format($str)
  778. // {
  779. // return strtoupper(implode('', str_split(str_replace(' ', '', $str), 2)));
  780. // }
  781. //}
  782. /**
  783. * Created by PhpStorm.
  784. * User: Mead
  785. * Date: 2019/9/5
  786. * Time: 9:36 PM
  787. */
  788. namespace App\Handlers\Weikemu;
  789. use GatewayClient\Gateway;
  790. use Illuminate\Support\Facades\Log;
  791. use Illuminate\Support\Facades\Redis;
  792. class BikeControl
  793. {
  794. const VIDEO_RETURN_BIKE = '01';
  795. const VIDEO_OPEN_LOCK = '02';
  796. // 还车成功,请规范停车
  797. const VIDEO_CIVILIZATION = '03';
  798. // 开锁成功
  799. const VIDEO_POWER_FAILURE = '04';
  800. // 请文明骑行规范停车
  801. const VIDEO_OFFLINE = '05';
  802. // 车辆已断电请回到服务区
  803. const VIDEO_ILLEGAL_MOVE = '06';
  804. // 车辆已下线
  805. const VIDEO_FIND_BIKE = '07';
  806. // 非法移动
  807. const VIDEO_KEEP_GOING = '08';
  808. // 临停成功将持续计费
  809. const VIDEO_BIKE_HERE = '09';
  810. // 向着诗和远方我们继续出发吧
  811. const VIDEO_BATTERY_EDGE = '0A';
  812. // 小喵在这里
  813. const VIDEO_POWER_CHANGE = '0B';
  814. // 靠近服务区边缘,服务区外将断电 10
  815. const VIDEO_GO_BEYOND = '0C';
  816. // 换电完成您辛苦了 11
  817. const VIDEO_NIGHT_SAFETY = '0D';
  818. // 您已出服务区请尽快骑回 12
  819. const VIDEO_NO_STOPPING = '0E';
  820. // 夜间出行注意安全 13
  821. const VIDEO_USE_OTHER = '10';
  822. // 当前为禁停区禁止停车 14
  823. const VIDEO_LOW_POWER = '11';
  824. // 空 15
  825. // 小喵生病了试试别的车吧 16
  826. const VIDEO_OCCUPIED = '12';
  827. //电量过低 17
  828. const VIDEO_RESERVED = '13';
  829. // 主人即将回来试试别的车吧 18
  830. const VIDEO_WARNING = '14';
  831. //小猫被预约了试试别的车吧 19
  832. const VIDEO_NO_STOP_ZONE = '15';
  833. // (带告警音)请停止偷窃行为 20
  834. const VIDEO_ALARMED = '16';
  835. // 您已进入禁停区 21
  836. const VIDEO_NO_STEALING = '17';
  837. // 车辆已报警请勿移动 22
  838. const VIDEO_BOUND = '18';
  839. //请停止偷窃行为 23
  840. const VIDEO_FALL = '19';
  841. // 设备已绑定 24
  842. const CACHE_KEY = 'cache:select';
  843. // 小喵摔倒了
  844. private static $start = '42 44';
  845. private static $registerAddress = 'node4:3238';
  846. /**
  847. * realLocation 3.2.2 实时位置上报参数设置
  848. *
  849. * @param $box_no
  850. * @param string $control 01:实时追踪开启,00:实时追踪关闭
  851. * @param int $interval 上报间隔 秒 量化值30
  852. * @param int $continued 持续时长(1-43200) 分钟
  853. * @return bool
  854. * @author Fx
  855. *
  856. */
  857. public static function realLocation($box_no, $control = "01", $interval = 1, $continued = 60)
  858. {
  859. $cmd = "23";
  860. $body = [
  861. self::getMsgId(),
  862. $control,// 1:实时追踪开启,0:实时追踪关闭
  863. str_pad(base_convert($interval, 10, 16), 4, 0, STR_PAD_LEFT),//上报间隔
  864. str_pad(base_convert($continued, 10, 16), 4, 0, STR_PAD_LEFT),//持续时长(1-43200)
  865. ];
  866. $send_msg = self::makeSendMsg($cmd, $body);
  867. return self::send($box_no, $send_msg, false);
  868. }
  869. /**
  870. * multipleConfigsSetting 3.2.3 综合配置参数设置
  871. *
  872. * @param $box_no
  873. * @param $arr
  874. * @return bool
  875. * @author Fx
  876. *
  877. */
  878. public static function multipleConfigsSetting($box_no, $arr)
  879. {
  880. $cmd = "2C";
  881. // ['ip' => $ip,'port' => $port,'bluetooth_name' => $bluetooth_name,'bluetooth_token' => $bluetooth_token,
  882. // 'is_auto_lock' => $is_auto_lock, 'auto_lock_time' => $auto_lock_time,
  883. // 'is_displacement' => $is_displacement, 'displacement_radius' => $displacement_radius,
  884. // 'is_shock' => $is_shock,
  885. // 'is_temperature' => $is_temperature,'temperature' => $temperature,
  886. // 'is_speeding' => $is_speeding,'speeding'=>$speeding,
  887. // 'motion_position_sampling_interval'=>$motion_position_sampling_interval,
  888. // 'motion_position_reporting_interval'=>$motion_position_reporting_interval,
  889. // 'static_position_reporting_interval'=>$static_position_reporting_interval];
  890. $ip = $arr['ip'];
  891. $port = $arr['port'];
  892. $bluetooth_name = $arr['bluetooth_name']; // 蓝牙名称
  893. $bluetooth_token = $arr['bluetooth_token']; //蓝牙token
  894. $is_auto_lock = $arr['is_auto_lock']; // 是否开启自动落锁1:自动落锁开启;0:关闭自动落锁
  895. $auto_lock_time = str_pad(base_convert($arr['auto_lock_time'], 10, 2), 7, 0, STR_PAD_LEFT); // 自动落锁时长,量化单位1分钟
  896. $is_displacement = $arr['is_displacement']; // 位移告警开启设置1:位移告警开启;0: 位移告警关闭
  897. $displacement_radius = str_pad(base_convert($arr['displacement_radius'], 10, 2), 7, 0, STR_PAD_LEFT); // 位移告警半径门限,取值范围0~126,量化单位10米
  898. $is_shock = $arr['is_shock'];//震动告警开启设置1:震动告警开启,0:震动告警关闭
  899. $is_temperature = $arr['is_temperature'];//温度告警开启设置。1:温度告警开启;0:温度告警关闭
  900. $temperature = str_pad(base_convert($arr['temperature'], 10, 2), 7, 0, STR_PAD_LEFT); // 温度告警门限,取值范围0~126,
  901. $is_speeding = $arr['is_speeding']; // 超速告警开启设置。1:超速告警开启;0:超速告警关闭
  902. $speeding = str_pad(base_convert($arr['speeding'] * 2, 10, 2), 7, 0, STR_PAD_LEFT); // 超速告警门限 量化单位2km/h,范围 0~126
  903. $motion_position_sampling_interval = $arr['motion_position_sampling_interval']; // 运动状态,位置采样间隔设置(默认1秒)
  904. $motion_position_reporting_interval = $arr['motion_position_reporting_interval']; // 运动状态,位置上报间隔设置
  905. $static_position_reporting_interval = $arr['static_position_reporting_interval']; // 静止状态,位置上报间隔设置
  906. $msg_id = self::getMsgId();
  907. $body = [
  908. $msg_id,
  909. str_pad(base_convert($motion_position_sampling_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置采样间隔设置(默认1秒)
  910. str_pad(base_convert($motion_position_reporting_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置上报间隔设置
  911. str_pad(base_convert($static_position_reporting_interval, 10, 16), 4, 0, STR_PAD_LEFT),// 静止状态,位置上报间隔设置
  912. str_pad(base_convert($displacement_radius . $is_displacement, 2, 16), 2, 0, STR_PAD_LEFT),// 位移告警
  913. str_pad(base_convert('0000000' . $is_shock, 2, 16), 2, 0, STR_PAD_LEFT),// 震动告警
  914. str_pad(base_convert($temperature . $is_temperature, 2, 16), 2, 0, STR_PAD_LEFT),// 温度告警
  915. str_pad(base_convert($speeding . $is_speeding, 2, 16), 2, 0, STR_PAD_LEFT),// 超速告警
  916. str_pad(base_convert($auto_lock_time . $is_auto_lock, 2, 16), 2, 0, STR_PAD_LEFT),// 自动落锁
  917. str_pad(base_convert($port, 10, 16), 4, 0, STR_PAD_LEFT),// 自动落锁
  918. str_pad(base_convert($ip, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
  919. str_pad($bluetooth_name, 10, 0, STR_PAD_LEFT),
  920. str_pad(base_convert($bluetooth_token, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
  921. '00 00 00 00 00 00'
  922. ];
  923. $send_msg = self::makeSendMsg($cmd, $body);
  924. return self::send($box_no, $send_msg, $msg_id);
  925. }
  926. public static function setBoxSetting($box_no, $arr)
  927. {
  928. $cmd = "2C";
  929. $auto_lock_time = str_pad(base_convert($arr['auto_lock_time'], 10, 2), 7, 0, STR_PAD_LEFT); // 自动落锁时长,量化单位1分钟
  930. $ipArr = explode('.', $arr['ip']);
  931. $ip =
  932. $msg_id = self::getMsgId();
  933. $body = [
  934. $msg_id,
  935. 'FF',// 运动状态,位置采样间隔设置(默认1秒)
  936. str_pad(base_convert($arr['motion_position_reporting_interval'], 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置上报间隔设置
  937. str_pad(base_convert($arr['static_position_reporting_interval'], 10, 16), 4, 0, STR_PAD_LEFT),// 静止状态,位置上报间隔设置
  938. 'FF',// 位移告警
  939. 'FF',// 震动告警
  940. 'FF',// 温度告警
  941. 'FF',// 超速告警
  942. str_pad(base_convert($auto_lock_time . '1', 2, 16), 2, 0, STR_PAD_LEFT),// 自动落锁
  943. 'FF FF',
  944. //str_pad(base_convert($arr['port'], 10, 16), 4, 0, STR_PAD_LEFT),// port
  945. 'FF FF FF FF',
  946. // str_pad(base_convert($arr['ip'], 10, 16), 8, 0, STR_PAD_LEFT),// ip
  947. 'FF FF FF FF FF FF FF FF FF FF',// 20位
  948. 'FF FF FF FF ',//
  949. 'FF FF FF FF FF FF'
  950. ];
  951. $send_msg = self::makeSendMsg($cmd, $body);
  952. // Log::info($send_msg);
  953. return self::send($box_no, $send_msg, $msg_id);
  954. }
  955. /**
  956. * reboot 重启中控
  957. *
  958. * @param $box_no
  959. * @param $reboot string 11:重启升级;01:重启不升级
  960. * @param $ip string 重启升级地址(域名或IP地址)
  961. * @param $port int 重启升级端口号
  962. * @param $path string 重启升级路径
  963. * @param $upFile string 重启升级文件名称
  964. * @return bool
  965. * @author Fx
  966. *
  967. */
  968. public static function reboot($box_no, $reboot = "01", $ip, $port, $path, $upFile)
  969. {
  970. $cmd = "25";
  971. $reboot = '000000' . $reboot; // 11:重启升级;01:重启不升级
  972. $msg_id = self::getMsgId();
  973. $body = [
  974. $msg_id,
  975. self::str2Hex($reboot, 2, 8),
  976. self::char2Hex($ip, 20),
  977. self::str2Hex($port, 10, 8),
  978. self::char2Hex($path, 20),
  979. self::char2Hex($upFile, 20),
  980. ];
  981. $send_msg = self::makeSendMsg($cmd, $body);
  982. return self::send($box_no, $send_msg, $msg_id);
  983. }
  984. /**
  985. * str2Hex 其他进制转16进制
  986. *
  987. * @param $str string 需要转的数据
  988. * @param $frombase int 需要转的进制
  989. * @param $pad_length int 长度
  990. * @return string
  991. * @author Fx
  992. *
  993. */
  994. private static function str2Hex($str, $frombase, $pad_length)
  995. {
  996. return str_pad(base_convert($str, $frombase, 16), $pad_length, 0, STR_PAD_LEFT);
  997. }
  998. /**
  999. * char2Hex char 转16进制
  1000. *
  1001. * @param $char
  1002. * @param $pad_length
  1003. * @return string
  1004. * @author Fx
  1005. *
  1006. */
  1007. private static function char2Hex($char, $pad_length)
  1008. {
  1009. return str_pad(bin2hex($char), $pad_length, 0, STR_PAD_LEFT);
  1010. }
  1011. /**
  1012. * nowBikeBatteryMSG 从定位包中获取电量
  1013. *
  1014. * @param $box_no
  1015. * @return bool
  1016. * @author Fx
  1017. *
  1018. */
  1019. public static function nowBikeBatteryMSG($box_no)
  1020. {
  1021. return self::nowBikeLocation($box_no);
  1022. }
  1023. /**
  1024. * nowBikeLocation 立即定位
  1025. *
  1026. * @param $box_no
  1027. * @return bool
  1028. * @author Fx
  1029. *
  1030. */
  1031. public static function nowBikeLocation($box_no)
  1032. {
  1033. return self::queryCmd($box_no, '00000001');
  1034. }
  1035. /**
  1036. * queryCmd 3.2.1 查询指令
  1037. *
  1038. * @param $box_no
  1039. * @return bool
  1040. * @author Fx
  1041. *
  1042. */
  1043. public static function queryCmd($box_no, $str2 = '00111101')
  1044. {
  1045. $cmd = "2B";
  1046. $body = [
  1047. self::getMsgId(),
  1048. str_pad(base_convert($str2, 2, 16), 2, 0, STR_PAD_LEFT)
  1049. ];
  1050. $send_msg = self::makeSendMsg($cmd, $body);
  1051. return self::send($box_no, $send_msg, false);
  1052. }
  1053. /**
  1054. * 获取序号(msg_id)
  1055. * @return string
  1056. * Author: Mead
  1057. */
  1058. private static function getMsgId()
  1059. {
  1060. $msg_id = str_pad(dechex(rand(0, 65535)), 4, "0", STR_PAD_LEFT);
  1061. return $msg_id;
  1062. }
  1063. /**
  1064. * 组装命令
  1065. * @param $cmd
  1066. * @param $msgID
  1067. * @return string
  1068. * User: Mead
  1069. */
  1070. private static function makeSendMsg($cmd, $body, $msg_id = false, $length = false)
  1071. {
  1072. if (is_array($body)) {
  1073. $body = self::arr2arr($body);
  1074. }
  1075. if (is_string($body)) {
  1076. $body = str_split($body, 2);
  1077. }
  1078. if ($length !== false) {
  1079. $length = str_pad($length, 4, '0', STR_PAD_LEFT);
  1080. } else {
  1081. $length = str_pad(dechex(count($body)), 4, '0', STR_PAD_LEFT);
  1082. }
  1083. if ($msg_id === false) {
  1084. $msg_id = self::getMsgId();
  1085. }
  1086. $header = [
  1087. $cmd,
  1088. $msg_id,
  1089. '00',
  1090. $length
  1091. ];
  1092. $response = self::formatArr($header, $body);
  1093. $response[] = self::verification($response);
  1094. return self::format(self::$start . implode('', $response));
  1095. }
  1096. /**
  1097. * 格式数组
  1098. * @param $arr
  1099. * @return array
  1100. * User: Mead
  1101. */
  1102. private static function arr2arr($arr)
  1103. {
  1104. $arr = implode('', $arr);
  1105. return str_split(str_replace(' ', '', $arr), 2);
  1106. }
  1107. /**
  1108. * 合并数组
  1109. * @return array
  1110. * User: Mead
  1111. */
  1112. private static function formatArr()
  1113. {
  1114. $args = func_get_args();
  1115. $arr = '';
  1116. foreach ($args as $arg) {
  1117. $arr .= implode('', $arg);
  1118. }
  1119. return str_split($arr, 2);
  1120. }
  1121. /**
  1122. * 校检
  1123. * @param $data
  1124. * @param $verification
  1125. * @return bool
  1126. * Author: Mead
  1127. */
  1128. protected static function verification($data)
  1129. {
  1130. $a = $b = 0;
  1131. for ($i = 0; $i < count($data); $i++) {
  1132. $a = $a + hexdec($data[$i]);
  1133. $b = $a + $b;
  1134. }
  1135. return str_pad(substr(dechex($a), -2), 2, 0, STR_PAD_LEFT) . str_pad(substr(dechex($b), -2), 2, 0, STR_PAD_LEFT);
  1136. }
  1137. /**
  1138. * 格式字符
  1139. * @param $str
  1140. * @return string
  1141. * User: Mead
  1142. */
  1143. private static function format($str)
  1144. {
  1145. return strtoupper(implode('', str_split(str_replace(' ', '', $str), 2)));
  1146. }
  1147. /**
  1148. * 发送数据
  1149. * @param $box_no
  1150. * @param $msg
  1151. * @return bool
  1152. * User: Mead
  1153. */
  1154. private static function send($box_no, $msg, $msg_id = false, $decode = true)
  1155. {
  1156. Gateway::$registerAddress = config('bike.bike_control_register_address');
  1157. if (Gateway::isUidOnline($box_no)) {
  1158. Gateway::sendToUid($box_no, '+NNMI,' . hex2bin(str_replace(' ', '', $msg . '0D0A')));
  1159. if ($msg_id !== false) {
  1160. $redis = Redis::connection();
  1161. $response = false;
  1162. $msg_id = strtolower(substr($msg, 6, 4));
  1163. for ($i = 1; $i <= 40; $i++) {
  1164. usleep(500000);
  1165. $data = $redis->get(self::CACHE_KEY . ':' . $box_no . ':' . $msg_id);
  1166. if ($data) {
  1167. Log::error('检查key:' . $msg_id);
  1168. Log::error($data);
  1169. $response = self::decodeData($data, $decode);
  1170. break;
  1171. }
  1172. if ($i == 20) {
  1173. //重试一次
  1174. Gateway::sendToUid($box_no, '+NNMI,' . hex2bin(str_replace(' ', '', $msg . '0D0A')));
  1175. }
  1176. }
  1177. return $response;
  1178. }
  1179. return true;
  1180. }
  1181. return false;
  1182. }
  1183. /**
  1184. * 解析车辆返回数据
  1185. * @param $data
  1186. * @return bool|mixed
  1187. */
  1188. public static function decodeData($data, $decode = true)
  1189. {
  1190. $array = explode('||', $data);
  1191. if (count($array) !== 2) return false;
  1192. list($type, $value) = $array;
  1193. if (!$decode) return $value;
  1194. switch ($type) {
  1195. case 'string':
  1196. return $value;
  1197. break;
  1198. case 'bool':
  1199. return (boolean)$data;
  1200. break;
  1201. case 'array':
  1202. return json_decode($value);
  1203. }
  1204. return false;
  1205. }
  1206. public static function rebootBox($box_no)
  1207. {
  1208. $cmd = "25";
  1209. $msg_id = self::getMsgId();
  1210. $body = [
  1211. $msg_id,
  1212. '01',// 0X02:重启升级;0X01:重启不升级
  1213. 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',// ip 20 bytes
  1214. 'FF FF FF FF FF FF FF FF FF FF ', // PORT 10 BYTES
  1215. 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF', // 重启升级路径
  1216. 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF', // 重启升级文件名称
  1217. ];
  1218. $send_msg = self::makeSendMsg($cmd, $body);
  1219. return self::send($box_no, $send_msg, $msg_id);
  1220. }
  1221. public static function maxecuspeedToMaxspeedpercent($maxecuspeed = 7)
  1222. {
  1223. $MAXSPEEDPERCENT = 100;
  1224. switch ($maxecuspeed) {
  1225. case 1:
  1226. $MAXSPEEDPERCENT = 70;
  1227. break;
  1228. case 2:
  1229. $MAXSPEEDPERCENT = 75;
  1230. break;
  1231. case 3:
  1232. $MAXSPEEDPERCENT = 80;
  1233. break;
  1234. case 4:
  1235. $MAXSPEEDPERCENT = 85;
  1236. break;
  1237. case 5:
  1238. $MAXSPEEDPERCENT = 90;
  1239. break;
  1240. case 6:
  1241. $MAXSPEEDPERCENT = 95;
  1242. break;
  1243. case 7:
  1244. $MAXSPEEDPERCENT = 100;
  1245. break;
  1246. }
  1247. return $MAXSPEEDPERCENT;
  1248. }
  1249. /**
  1250. * settingVoice 语音设置
  1251. *
  1252. * @param $box_no
  1253. * @param $voice_no
  1254. * @param $ip
  1255. * @param $port
  1256. * @param $path
  1257. * @param $upFile
  1258. * @return bool
  1259. * @author Fx
  1260. *
  1261. */
  1262. public static function settingVoice($box_no, $voice_no, $ip, $port, $path, $upFile)
  1263. {
  1264. $cmd = "2A";
  1265. $msg_id = self::getMsgId();
  1266. $body = [
  1267. $msg_id,
  1268. '00',
  1269. self::str2Hex($voice_no, 10, 2),
  1270. self::char2Hex($ip, 20),
  1271. self::str2Hex($port, 10, 8),
  1272. self::char2Hex($path, 20),
  1273. self::char2Hex($upFile, 20),
  1274. ];
  1275. $send_msg = self::makeSendMsg($cmd, $body);
  1276. return self::send($box_no, $send_msg, $msg_id);
  1277. }
  1278. /**
  1279. * guardSwitch 3.2.7 防盗开关设置
  1280. *
  1281. * @param $box_no
  1282. * @param $control 00:关闭 01:开启
  1283. * @return bool
  1284. * @author Fx
  1285. *
  1286. */
  1287. public static function guardSwitch($box_no, $control)
  1288. {
  1289. $cmd = "2E";
  1290. $msg_id = self::getMsgId();
  1291. $body = [
  1292. $msg_id,
  1293. $control
  1294. ];
  1295. $send_msg = self::makeSendMsg($cmd, $body);
  1296. return self::send($box_no, $send_msg, $msg_id);
  1297. }
  1298. /**
  1299. * batterySwitch 3.2.8 电池仓开关设置
  1300. *
  1301. * @param $box_no
  1302. * @return bool
  1303. * @author Fx
  1304. *
  1305. */
  1306. public static function openBatteryLock($box_no)
  1307. {
  1308. $cmd = "2F";
  1309. $msg_id = self::getMsgId();
  1310. $body = [
  1311. $msg_id,
  1312. '01',
  1313. ];
  1314. $send_msg = self::makeSendMsg($cmd, $body);
  1315. return self::send($box_no, $send_msg, false);
  1316. }
  1317. /**
  1318. * limitSpeed 限速
  1319. *
  1320. * @param $box_no
  1321. * @param $limit int 限速[%]
  1322. * @return bool
  1323. * @author Fx
  1324. *
  1325. */
  1326. public static function limitSpeed($box_no, $limit)
  1327. {
  1328. $cmd = "30";
  1329. $body = [
  1330. self::getMsgId(),
  1331. self::str2Hex($limit, 10, 2),// 限速[%]
  1332. ];
  1333. $send_msg = self::makeSendMsg($cmd, $body);
  1334. return self::send($box_no, $send_msg, false);
  1335. }
  1336. /**
  1337. * undervoltageProtection 3.2.10 控制器欠压保护设置
  1338. *
  1339. * @param $box_no
  1340. * @param $limit int 控制器欠压保护值,量单位1mv
  1341. * @return bool
  1342. * @author Fx
  1343. *
  1344. */
  1345. public static function undervoltageProtection($box_no, $limit)
  1346. {
  1347. $cmd = "31";
  1348. $body = [
  1349. self::getMsgId(),
  1350. self::str2Hex($limit, 10, 4),// 限速[%]
  1351. ];
  1352. $send_msg = self::makeSendMsg($cmd, $body);
  1353. return self::send($box_no, $send_msg, false);
  1354. }
  1355. /**
  1356. * currentLimitingProtection 3.2.11 控制器限流保护设置
  1357. *
  1358. * @param $box_no
  1359. * @param $limit int 控制器限流保护值,量化单位1mA
  1360. * @return bool
  1361. * @author Fx
  1362. *
  1363. */
  1364. public static function currentLimitingProtection($box_no, $limit)
  1365. {
  1366. $cmd = "32";
  1367. $body = [
  1368. self::getMsgId(),
  1369. self::str2Hex($limit, 10, 4),//
  1370. ];
  1371. $send_msg = self::makeSendMsg($cmd, $body);
  1372. return self::send($box_no, $send_msg, false);
  1373. }
  1374. /**
  1375. * slowReboot 3.2.12 控制器缓启动设置
  1376. *
  1377. * @param $box_no
  1378. * @param $control string 01,缓启动;00,快启动
  1379. * @return bool
  1380. * @author Fx
  1381. *
  1382. */
  1383. public static function slowReboot($box_no, $control)
  1384. {
  1385. $cmd = "33";
  1386. $body = [
  1387. self::getMsgId(),
  1388. $control,
  1389. ];
  1390. $send_msg = self::makeSendMsg($cmd, $body);
  1391. return self::send($box_no, $send_msg, false);
  1392. }
  1393. /**
  1394. * lampSwitch 3.2.13 控制器大灯设置
  1395. *
  1396. * @param $box_no
  1397. * @param $control string 01,大灯开;00,大灯关
  1398. * @return bool
  1399. * @author Fx
  1400. *
  1401. */
  1402. public static function lampSwitch($box_no, $control)
  1403. {
  1404. $cmd = "34";
  1405. $body = [
  1406. self::getMsgId(),
  1407. $control,
  1408. ];
  1409. $send_msg = self::makeSendMsg($cmd, $body);
  1410. return self::send($box_no, $send_msg, false);
  1411. }
  1412. /**
  1413. * openLock 开锁
  1414. *
  1415. * @param $box_no
  1416. * @return bool
  1417. * @author Fx
  1418. *
  1419. */
  1420. public static function openLock($box_no)
  1421. {
  1422. $re = self::electricSwitchControl($box_no, '01');
  1423. if ($re) {
  1424. self::orderStatus($box_no, '01');
  1425. self::playVoice($box_no, self::VIDEO_OPEN_LOCK);
  1426. return true;
  1427. }
  1428. return false;
  1429. }
  1430. /**
  1431. * electricSwitchControl 电门控制
  1432. *
  1433. * @param $box_no
  1434. * @param $control 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
  1435. * @return bool
  1436. * @author Fx
  1437. *
  1438. */
  1439. public static function electricSwitchControl($box_no, $control = "01")
  1440. {
  1441. $cmd = "2D";
  1442. $msg_id = self::getMsgId();
  1443. $body = [
  1444. $msg_id,
  1445. $control,// 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
  1446. ];
  1447. $send_msg = self::makeSendMsg($cmd, $body);
  1448. return self::send($box_no, $send_msg, false);
  1449. }
  1450. /**
  1451. * orderStatus
  1452. *
  1453. * @param $box_no
  1454. * @param $control string 01:接单开启;00:接单关闭
  1455. * @return bool
  1456. * @author Fx
  1457. *
  1458. */
  1459. public static function orderStatus($box_no, $control)
  1460. {
  1461. $cmd = "35";
  1462. $body = [
  1463. self::getMsgId(),
  1464. $control,
  1465. ];
  1466. $send_msg = self::makeSendMsg($cmd, $body);
  1467. return self::send($box_no, $send_msg, false);
  1468. }
  1469. /**
  1470. * 播放语音
  1471. * @param $box_no
  1472. * @return bool
  1473. * User: Mead
  1474. */
  1475. public static function playVoice($box_no, $voice_no, $msg_id = false)
  1476. {
  1477. $cmd = "2A";
  1478. $body = [
  1479. self::getMsgId(),
  1480. '01',
  1481. $voice_no,
  1482. 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
  1483. 'FF FF FF FF',
  1484. 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
  1485. 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
  1486. ];
  1487. $send_msg = self::makeSendMsg($cmd, $body);
  1488. return self::send($box_no, $send_msg, false);
  1489. }
  1490. /**
  1491. * closeLock 关锁 (设防)
  1492. *
  1493. * @param $box_no
  1494. * @return bool
  1495. * @author Fx
  1496. *
  1497. */
  1498. public static function closeLock($box_no)
  1499. {
  1500. $re = self::electricSwitchControl($box_no, '02');
  1501. if ($re) {
  1502. self::orderStatus($box_no, '00');
  1503. self::playVoice($box_no, self::VIDEO_RETURN_BIKE);
  1504. return true;
  1505. }
  1506. return false;
  1507. }
  1508. /**
  1509. * closeLock 临时关锁 (设防)
  1510. *
  1511. * @param $box_no
  1512. * @return bool
  1513. * @author Fx
  1514. *
  1515. */
  1516. public static function temporaryCloseLock($box_no)
  1517. {
  1518. $re = self::electricSwitchControl($box_no, '02');
  1519. if ($re) {
  1520. self::playVoice($box_no, self::VIDEO_FIND_BIKE);
  1521. return true;
  1522. }
  1523. return false;
  1524. }
  1525. /**
  1526. * temporaryOpnLock 临时开锁
  1527. *
  1528. * @param $box_no
  1529. * @return bool
  1530. * @author Fx
  1531. *
  1532. */
  1533. public static function temporaryOpnLock($box_no)
  1534. {
  1535. $re = self::electricSwitchControl($box_no, '01');
  1536. if ($re) {
  1537. self::playVoice($box_no, self::VIDEO_KEEP_GOING);
  1538. return true;
  1539. }
  1540. return false;
  1541. }
  1542. /**
  1543. * closeLockNoGuard 关锁 (不设防) 失能
  1544. *
  1545. * @param $box_no
  1546. * @return bool
  1547. * @author Fx
  1548. *
  1549. */
  1550. public static function outAreaLoseElectric($box_no)
  1551. {
  1552. self::playVoice($box_no, self::VIDEO_GO_BEYOND);
  1553. return self::electricSwitchControl($box_no, '00');
  1554. }
  1555. /**
  1556. * outAreaGetElectric 开锁 获能
  1557. *
  1558. * @param $box_no
  1559. * @return bool
  1560. * @author Fx
  1561. *
  1562. */
  1563. public static function outAreaGetElectric($box_no)
  1564. {
  1565. self::playVoice($box_no, self::VIDEO_KEEP_GOING);
  1566. return self::electricSwitchControl($box_no, '01');
  1567. }
  1568. /**
  1569. * 寻铃
  1570. * @param $box_no
  1571. * @return bool
  1572. * Author: Mead
  1573. */
  1574. public static function bellBike($box_no)
  1575. {
  1576. return self::playVoice($box_no, self::VIDEO_BIKE_HERE, true);
  1577. }
  1578. public static function queryConfig($box_no, $str2 = '00000100')
  1579. {
  1580. $cmd = "2B";
  1581. $msg_id = self::getMsgId();
  1582. $body = [
  1583. $msg_id,
  1584. str_pad(base_convert($str2, 2, 16), 2, 0, STR_PAD_LEFT)
  1585. ];
  1586. $send_msg = self::makeSendMsg($cmd, $body, $msg_id);
  1587. return self::send($box_no, $send_msg, $msg_id);
  1588. }
  1589. public static function getBikeResponse($box_no, $msg_id, $decode = true)
  1590. {
  1591. $redis = Redis::connection();
  1592. $response = false;
  1593. for ($i = 1; $i <= 30; $i++) {
  1594. usleep(500000);
  1595. $data = $redis->get(self::CACHE_KEY . ':' . $box_no . ':' . $msg_id);
  1596. if ($data) {
  1597. $response = self::decodeData($data, $decode);
  1598. break;
  1599. }
  1600. }
  1601. return $response;
  1602. }
  1603. /**
  1604. * 10 进制转 16
  1605. */
  1606. private static function decToHex($hex)
  1607. {
  1608. return str_pad(base_convert($hex, 10, 16), 2, 0, STR_PAD_LEFT);
  1609. }
  1610. }