WarningTransform.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Mead
  5. * Date: 2019/9/3
  6. * Time: 8:05 PM
  7. */
  8. namespace App\Servers\Weikemu\Transforms;
  9. use App\Maps\WarningLogMap;
  10. use App\Models\BoxSettingTraitModel;
  11. use App\Models\WarningLogTraitModel;
  12. use App\Servers\BaseServer;
  13. use App\Servers\Weikemu\BikeControl;
  14. use Workerman\Lib\Timer;
  15. /**
  16. * 告警报文
  17. * Class WarningServer
  18. * @package App\Servers\Weikemu
  19. */
  20. class WarningTransform extends BaseServer
  21. {
  22. use BoxSettingTraitModel, WarningLogTraitModel;
  23. public static $typeMaps = [
  24. '震动告警',
  25. '外部电池移除',
  26. '位移告警',
  27. '温度告警',
  28. '自动落锁(ACC断开)',
  29. '',
  30. '',
  31. '终端电量告警',
  32. '外部电量告警',
  33. '外部电池接入',
  34. 'ACC接通',
  35. 'ACC断开',
  36. '移动告警',
  37. '后座锁关闭',
  38. '后座锁打开'
  39. ];
  40. /**
  41. * 处理设备序列号
  42. * @param $no
  43. * @return bool|string
  44. * User: Mead
  45. */
  46. private
  47. static function box_no($no)
  48. {
  49. return substr($no, 0, 9);
  50. }
  51. public function main($body)
  52. {
  53. $data = $this->decode($body);
  54. $type = 100;
  55. foreach ($data['warning'] as $k => $v) {
  56. if ($v) {
  57. $type = $k;
  58. break;
  59. }
  60. }
  61. $box_no = $data['box_no'];
  62. $bike_no = $_SESSION['bike_no'];
  63. switch ($type) {
  64. case 0:
  65. // 震动告警
  66. self::log('震动告警:' . $box_no, 'WARNING');
  67. $type = WarningLogMap::TYPE_WARNING_BIKE_SHOCK;
  68. $error_grade = WarningLogMap::ERROR_GRADE_MINOR;
  69. if ($this->is_throw_num_time($box_no, 'warning_log_' . $type, 3, 10)) {
  70. $this->warningLog($bike_no, $box_no, $data['status'], $body, $type, ($error_grade + 1));
  71. } else {
  72. $this->warningLog($bike_no, $box_no, $data['status'], $body, $type, $error_grade);
  73. }
  74. break;
  75. case 1:
  76. //外部电池移除
  77. self::log('外部电池移除:' . $box_no, 'WARNING');
  78. $this->redis->setex("cache:warnning:{$type}:{$box_no}", 320, 1);
  79. Timer::add(300, function ($box_no, $type, $bike_no, $body, $data) {
  80. // 检测电池是否接入
  81. if ($this->redis->exists("cache:warnning:{$type}:{$box_no}")) {
  82. $type = WarningLogMap::TYPE_WARNING_CLOSE_ELECTRIC;
  83. $error_grade = WarningLogMap::ERROR_GRADE_MINOR;
  84. $this->warningLog($bike_no, $box_no, $data['status'], $body, $type, $error_grade);
  85. }
  86. }, array($box_no, $type, $bike_no, $body, $data), false);
  87. break;
  88. case 2:
  89. //位移告警
  90. self::log('位移告警:' . $box_no, 'WARNING');
  91. $type = WarningLogMap::TYPE_WARNING_WHEEL_MOVE;
  92. $error_grade = WarningLogMap::ERROR_GRADE_MINOR;
  93. $this->warningLog($bike_no, $box_no, $data['status'], $body, $type, $error_grade);
  94. break;
  95. case 3:
  96. //温度告警
  97. self::log('温度告警:' . $box_no, 'WARNING');
  98. break;
  99. case 4:
  100. //自动落锁(ACC断开)
  101. self::log('自动落锁:' . $box_no, 'WARNING');
  102. $status = json_decode(file_get_contents(Config['close_order_api_url'] . "&box_no={$box_no}&bike_no={$bike_no}&type=静止30分钟"), true);
  103. break;
  104. case 5:
  105. case 6:
  106. break;
  107. case 7:
  108. // 终端电量告警
  109. self::log('终端电量告警:' . $box_no, 'WARNING');
  110. $type = WarningLogMap::TYPE_BATTERY_LOW;
  111. $error_grade = WarningLogMap::ERROR_GRADE_MINOR;
  112. $this->warningLog($bike_no, $box_no, $data['status'], $body, $type, $error_grade);
  113. break;
  114. case 8:
  115. // 外部电量告警
  116. self::log('外部电量告警:' . $box_no, 'WARNING');
  117. $status = json_decode(file_get_contents(Config['close_order_api_url'] . "&box_no={$box_no}&bike_no={$bike_no}&type=电量低&position=4"), true);
  118. self::log($box_no, 'LOCATION_BATTERY_LOW_AUTO_ORDER', self::$LOG_COMMON);
  119. break;
  120. case 9:
  121. // 外部电池接入
  122. self::log('外部电池接入:' . $box_no, 'WARNING');
  123. //删除断电检测
  124. $this->redis->del("cache:warnning:1:{$box_no}");
  125. //删除电池缓存
  126. $key = "cache:min:update_stop_bike_battery:{$box_no}";
  127. $this->redis->del($key);
  128. $this->redis->setex("cache:open_battery:{$box_no}", 60, 1);
  129. BikeControl::nowBoxStatus($box_no);
  130. Timer::add(30, function ($box_no) {
  131. BikeControl::nowBoxStatus($box_no);
  132. }, array($box_no), false);
  133. Timer::add(60, function ($box_no) {
  134. BikeControl::nowBoxStatus($box_no);
  135. }, array($box_no), false);
  136. break;
  137. case 10:
  138. //ACC接通
  139. self::log('ACC接通:' . $box_no, 'WARNING');
  140. break;
  141. case 11:
  142. //ACC断开
  143. self::log('ACC断开:' . $box_no, 'WARNING');
  144. break;
  145. case 12:
  146. //移动告警
  147. self::log('移动告警:' . $box_no, 'WARNING');
  148. $type = WarningLogMap::TYPE_WARNING_BIKE_SHOCK;
  149. $error_grade = WarningLogMap::ERROR_GRADE_MINOR;
  150. $this->warningLog($bike_no, $box_no, $data['status'], $body, $type, $error_grade);
  151. break;
  152. case 13:
  153. //后座锁关闭
  154. self::log('后座锁关闭:' . $box_no, 'WARNING');
  155. BikeControl::nowBoxStatus($box_no);
  156. break;
  157. case 14:
  158. //后座锁打开
  159. self::log('后座锁打开:' . $box_no, 'WARNING');
  160. break;
  161. }
  162. return $this->response();
  163. }
  164. /**
  165. * 解析装载的状态消息
  166. * @param $body
  167. * @return array
  168. * User: Mead
  169. */
  170. private function decode($body)
  171. {
  172. $top34Data = $this->decodeWeiKeMuTop34($body);
  173. $i = 34;
  174. // 告警消息
  175. $warning = self::stitching($body, $i, 2); // i=34
  176. $i += 2;
  177. // 定位类型
  178. $location_type = self::stitching($body, $i, 1); // i=36
  179. $i += 1;
  180. //ACC状态
  181. $acc_status = self::stitching($body, $i, 1); // i=37
  182. $i += 1;
  183. // 动态计算
  184. $yjlx = self::stitching($body, $i, -1); // i=38
  185. return array_merge($top34Data, [
  186. 'warning' => self::handleWarning($warning),
  187. 'location_type' => self::handleLocationType($location_type),//0为基站定位 1为卫星定位
  188. 'acc_status' => self::handleACCStatus($acc_status),// 1:ACC接通;0:ACC断开
  189. ]);
  190. }
  191. /**
  192. * handleWarning 解析告警
  193. *
  194. * @param $warning
  195. * @param int $offset
  196. * @param int $len
  197. * @return array
  198. * @author Fx
  199. *
  200. */
  201. private static function handleWarning($warning, $offset = 0, $len = 16)
  202. {
  203. $data = self::handleU2($warning);
  204. return array_slice($data, $offset, $len);
  205. }
  206. private static function handleLocationType($location_type)
  207. {
  208. $data = self::handleU1($location_type);
  209. return $data[0];
  210. }
  211. private static function handleACCStatus($acc_status)
  212. {
  213. $data = self::handleU1($acc_status);
  214. return $data[0];
  215. }
  216. /**
  217. * 告警响应
  218. * @param $login_type
  219. * @return array
  220. * User: Mead
  221. */
  222. public function response($login_type = '00')
  223. {
  224. $body = [
  225. '5b',
  226. '0000'
  227. ];
  228. return $body;
  229. }
  230. }