<?php
///**
// * Created by PhpStorm.
// * User: Mead
// * Date: 2019/9/5
// * Time: 9:36 PM
// */
//
//namespace App\Handlers\Weikemu;
//
//
//use GatewayClient\Gateway;
//use Illuminate\Support\Facades\Redis;
//
//class  BikeControl
//{
//    private static $start = '42 44';
//
//    private static $registerAddress = 'node1:2238';
//
//    //    还车成功,请规范停车
//    const VIDEO_RETURN_BIKE = '01';
////   开锁成功
//    const VIDEO_OPEN_LOCK = '02';
////    请文明骑行规范停车
//    const VIDEO_CIVILIZATION = '03';
////    车辆已断电请回到服务区
//    const VIDEO_POWER_FAILURE = '04';
////    车辆已下线
//    const VIDEO_OFFLINE = '05';
////    非法移动
//    const VIDEO_ILLEGAL_MOVE = '06';
////    临停成功将持续计费
//    const VIDEO_FIND_BIKE = '07';
////    向着诗和远方我们继续出发吧
//    const VIDEO_KEEP_GOING = '08';
////    小喵在这里
//    const VIDEO_BIKE_HERE = '09';
////    靠近服务区边缘,服务区外将断电 10
//    const VIDEO_BATTERY_EDGE = '0A';
////    换电完成您辛苦了 11
//    const VIDEO_POWER_CHANGE = '0B';
////    您已出服务区请尽快骑回 12
//    const VIDEO_GO_BEYOND = '0C';
////     夜间出行注意安全 13
//    const VIDEO_NIGHT_SAFETY = '0D';
////    当前为禁停区禁止停车 14
//    const VIDEO_NO_STOPPING = '0E';
//    // 空 15
//
//    // 小喵生病了试试别的车吧 16
//    const VIDEO_USE_OTHER = '10';
//
//    //电量过低 17
//    const VIDEO_LOW_POWER = '11';
//    // 主人即将回来试试别的车吧 18
//    const VIDEO_OCCUPIED = '12';
//    //小猫被预约了试试别的车吧 19
//    const VIDEO_RESERVED = '13';
//    // (带告警音)请停止偷窃行为 20
//    const VIDEO_WARNING = '14';
//    // 您已进入禁停区 21
//    const VIDEO_NO_STOP_ZONE = '15';
//    // 车辆已报警请勿移动 22
//    const VIDEO_ALARMED = '16';
//    //请停止偷窃行为 23
//    const VIDEO_NO_STEALING = '17';
//    // 设备已绑定 24
//    const VIDEO_BOUND = '18';
//    // 小喵摔倒了
//    const VIDEO_FALL = '19';
//
//    /**
//     * 播放语音
//     * @param $box_no
//     * @return bool
//     * User: Mead
//     */
//    public static function playVoice($box_no, $voice_no)
//    {
//        $cmd = "2A";
//
//        $body = [
//            self::getMsgId(),
//            '01',
//            $voice_no,
//            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
//            'FF FF FF FF',
//            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
//            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * queryCmd 3.2.1    查询指令
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function queryCmd($box_no, $str2 = '00111101')
//    {
//        //  echo 'queryCmd' . PHP_EOL;
//        $cmd = "2B";
//
////        $str2 = '00111101'; // 3d
//        $body = [
//            self::getMsgId(),
//            str_pad(base_convert($str2, 2, 16), 2, 0, STR_PAD_LEFT)
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        // echo $send_msg . PHP_EOL;
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * electricSwitchControl  电门控制
//     *
//     * @param $box_no
//     * @param $control 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function electricSwitchControl($box_no, $control = "01")
//    {
////        echo 'kaiguansuo' . PHP_EOL;
//        $cmd = "2D";
//
//        $body = [
//            self::getMsgId(),
//            $control,// 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * realLocation 3.2.2    实时位置上报参数设置
//     *
//     * @param $box_no
//     * @param string $control 01:实时追踪开启,00:实时追踪关闭
//     * @param int $interval 上报间隔  秒 量化值30
//     * @param int $continued 持续时长(1-43200) 分钟
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function realLocation($box_no, $control = "01", $interval = 1, $continued = 60)
//    {
////        $box_no = '868626040174578';
//        $cmd = "23";
//
//        $body = [
//            self::getMsgId(),
//            $control,// 1:实时追踪开启,0:实时追踪关闭
//            str_pad(base_convert($interval, 10, 16), 4, 0, STR_PAD_LEFT),//上报间隔
//            str_pad(base_convert($continued, 10, 16), 4, 0, STR_PAD_LEFT),//持续时长(1-43200)
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
////        var_dump($body);
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * multipleConfigsSetting 3.2.3    综合配置参数设置
//     *
//     * @param $box_no
//     * @param $arr
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function multipleConfigsSetting($box_no, $arr)
//    {
//
//
//        $cmd = "2C";
////        ['ip' => $ip,'port' => $port,'bluetooth_name' => $bluetooth_name,'bluetooth_token' => $bluetooth_token,
////                                                   'is_auto_lock' => $is_auto_lock, 'auto_lock_time' => $auto_lock_time,
////                                                   'is_displacement' => $is_displacement, 'displacement_radius' => $displacement_radius,
////                                                   'is_shock' => $is_shock,
////                                                   'is_temperature' => $is_temperature,'temperature' => $temperature,
////                                                   'is_speeding' => $is_speeding,'speeding'=>$speeding,
////                                                   'motion_position_sampling_interval'=>$motion_position_sampling_interval,
////                                                   'motion_position_reporting_interval'=>$motion_position_reporting_interval,
////                                                   'static_position_reporting_interval'=>$static_position_reporting_interval];
//        $ip = $arr['ip'];
//        $port = $arr['port'];
//        $bluetooth_name = $arr['bluetooth_name']; // 蓝牙名称
//        $bluetooth_token = $arr['bluetooth_token']; //蓝牙token
//        $is_auto_lock = $arr['is_auto_lock']; // 是否开启自动落锁1:自动落锁开启;0:关闭自动落锁
//        $auto_lock_time = str_pad(base_convert($arr['auto_lock_time'], 10, 2), 7, 0, STR_PAD_LEFT); // 自动落锁时长,量化单位1分钟
//
//        $is_displacement = $arr['is_displacement']; // 位移告警开启设置1:位移告警开启;0: 位移告警关闭
//        $displacement_radius = str_pad(base_convert($arr['displacement_radius'], 10, 2), 7, 0, STR_PAD_LEFT); // 位移告警半径门限,取值范围0~126,量化单位10米
//
//        $is_shock = $arr['is_shock'];//震动告警开启设置1:震动告警开启,0:震动告警关闭
//
//        $is_temperature = $arr['is_temperature'];//温度告警开启设置。1:温度告警开启;0:温度告警关闭
//        $temperature = str_pad(base_convert($arr['temperature'], 10, 2), 7, 0, STR_PAD_LEFT); // 温度告警门限,取值范围0~126,
//
//        $is_speeding = $arr['is_speeding']; // 超速告警开启设置。1:超速告警开启;0:超速告警关闭
//        $speeding = str_pad(base_convert($arr['speeding'] * 2, 10, 2), 7, 0, STR_PAD_LEFT); // 超速告警门限 量化单位2km/h,范围 0~126
//        $motion_position_sampling_interval = $arr['motion_position_sampling_interval']; // 运动状态,位置采样间隔设置(默认1秒)
//        $motion_position_reporting_interval = $arr['motion_position_reporting_interval']; // 运动状态,位置上报间隔设置
//        $static_position_reporting_interval = $arr['static_position_reporting_interval']; // 静止状态,位置上报间隔设置
//
//
//        $body = [
//            self::getMsgId(),
//            str_pad(base_convert($motion_position_sampling_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置采样间隔设置(默认1秒)
//            str_pad(base_convert($motion_position_reporting_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置上报间隔设置
//            str_pad(base_convert($static_position_reporting_interval, 10, 16), 4, 0, STR_PAD_LEFT),// 静止状态,位置上报间隔设置
//            str_pad(base_convert($displacement_radius . $is_displacement, 2, 16), 2, 0, STR_PAD_LEFT),// 位移告警
//            str_pad(base_convert('0000000' . $is_shock, 2, 16), 2, 0, STR_PAD_LEFT),// 震动告警
//            str_pad(base_convert($temperature . $is_temperature, 2, 16), 2, 0, STR_PAD_LEFT),// 温度告警
//            str_pad(base_convert($speeding . $is_speeding, 2, 16), 2, 0, STR_PAD_LEFT),// 超速告警
//            str_pad(base_convert($auto_lock_time . $is_auto_lock, 2, 16), 2, 0, STR_PAD_LEFT),// 自动落锁
//            str_pad(base_convert($port, 10, 16), 4, 0, STR_PAD_LEFT),// 自动落锁
//            str_pad(base_convert($ip, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
//            str_pad($bluetooth_name, 10, 0, STR_PAD_LEFT),
//            str_pad(base_convert($bluetooth_token, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
//            '00 00 00 00 00 00'
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * reboot  重启中控
//     *
//     * @param $box_no
//     * @param  $reboot string  11:重启升级;01:重启不升级
//     * @param $ip   string    重启升级地址(域名或IP地址)
//     * @param $port int   重启升级端口号
//     * @param $path  string 重启升级路径
//     * @param $upFile string 重启升级文件名称
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function reboot($box_no, $reboot = "01", $ip, $port, $path, $upFile)
//    {
////        $box_no = '868626040174578';
//        $cmd = "25";
////        $reboot = '000000' . $reboot; // 11:重启升级;01:重启不升级
//
//
//        $body = [
//            self::getMsgId(),
//            self::str2Hex($reboot, 2, 8),
//            self::char2Hex($ip, 20),
//            self::str2Hex($port, 10, 8),
//            self::char2Hex($path, 20),
//            self::char2Hex($upFile, 20),
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * settingVoice  语音设置
//     *
//     * @param $box_no
//     * @param $voice_no
//     * @param $ip
//     * @param $port
//     * @param $path
//     * @param $upFile
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function settingVoice($box_no, $voice_no, $ip, $port, $path, $upFile)
//    {
//
//        $cmd = "2A";
//
//        $body = [
//            self::getMsgId(),
//            '00',
//            self::str2Hex($voice_no, 10, 2),
//            self::char2Hex($ip, 20),
//            self::str2Hex($port, 10, 8),
//            self::char2Hex($path, 20),
//            self::char2Hex($upFile, 20),
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * guardSwitch 3.2.7    防盗开关设置
//     *
//     * @param $box_no
//     * @param $control 00:关闭  01:开启
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function guardSwitch($box_no, $control)
//    {
////        echo 'guard' . PHP_EOL;
//
//        $cmd = "2E";
//
//        $body = [
//            self::getMsgId(),
//            $control
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * batterySwitch 3.2.8    电池仓开关设置
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function batterySwitch($box_no)
//    {
////        echo 'batterySwitch' . PHP_EOL;
//
//        $cmd = "2F";
//
//        $body = [
//            self::getMsgId(),
//            '01',
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * limitSpeed  限速
//     *
//     * @param $box_no
//     * @param $limit int   限速[%]
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function limitSpeed($box_no, $limit)
//    {
//
//        $cmd = "30";
//
//        $body = [
//            self::getMsgId(),
//            self::str2Hex($limit, 10, 2),// 限速[%]
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * undervoltageProtection 3.2.10    控制器欠压保护设置
//     *
//     * @param $box_no
//     * @param $limit  int 控制器欠压保护值,量单位1mv
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function undervoltageProtection($box_no, $limit)
//    {
//
//        $cmd = "31";
//
//        $body = [
//            self::getMsgId(),
//            self::str2Hex($limit, 10, 4),// 限速[%]
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//
//    /**
//     * currentLimitingProtection 3.2.11    控制器限流保护设置
//     *
//     * @param $box_no
//     * @param $limit int 控制器限流保护值,量化单位1mA
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function currentLimitingProtection($box_no, $limit)
//    {
//
//        $cmd = "32";
//
//        $body = [
//            self::getMsgId(),
//            self::str2Hex($limit, 10, 4),//
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * slowReboot 3.2.12    控制器缓启动设置
//     *
//     * @param $box_no
//     * @param $control string 01,缓启动;00,快启动
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function slowReboot($box_no, $control)
//    {
//
//        $cmd = "33";
//
//        $body = [
//            self::getMsgId(),
//            $control,
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * lampSwitch 3.2.13    控制器大灯设置
//     *
//     * @param $box_no
//     * @param $control string 01,大灯开;00,大灯关
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function lampSwitch($box_no, $control)
//    {
//
//        $cmd = "34";
//
//        $body = [
//            self::getMsgId(),
//            $control,
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//
//    /**
//     * orderStatus
//     *
//     * @param $box_no
//     * @param $control string 01:接单开启;00:接单关闭
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function orderStatus($box_no, $control)
//    {
//        $cmd = "35";
//
//        $body = [
//            self::getMsgId(),
//            $control,
//        ];
//
//        $send_msg = self::makeSendMsg($cmd, $body);
//
//        return self::send($box_no, $send_msg);
//    }
//
//    /**
//     * nowBikeLocation 立即定位
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function nowBikeLocation($box_no)
//    {
//        //删除ridis位置缓存
//        self::delRedisCache($box_no, 'update_bike_location');
//        return self::queryCmd($box_no, '00000001');
//    }
//
//
//    /**
//     * openLock  开锁
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function openLock($box_no)
//    {
//        self::playVoice($box_no, self::VIDEO_OPEN_LOCK);
//        self::orderStatus($box_no, '01');
//        return self::electricSwitchControl($box_no, '01');
//    }
//
//    /**
//     * closeLock 关锁 (设防)
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function closeLock($box_no)
//    {
//        self::playVoice($box_no, self::VIDEO_RETURN_BIKE);
//        self::orderStatus($box_no, '00');
//        return self::electricSwitchControl($box_no, '02');
//    }
//
//    /**
//     * closeLock 临时关锁 (设防)
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function temporaryCloseLock($box_no)
//    {
//        self::playVoice($box_no, self::VIDEO_FIND_BIKE);
//        return self::electricSwitchControl($box_no, '02');
//    }
//
//    /**
//     * temporaryOpnLock  临时开锁
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function temporaryOpnLock($box_no)
//    {
//        self::playVoice($box_no, self::VIDEO_KEEP_GOING);
//        return self::electricSwitchControl($box_no, '01');
//    }
//
//    /**
//     * closeLockNoGuard 关锁 (不设防)  失能
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function outAreaLoseElectric($box_no)
//    {
//        self::playVoice($box_no, self::VIDEO_GO_BEYOND);
//        return self::electricSwitchControl($box_no, '00');
//    }
//
//    /**
//     * outAreaGetElectric  开锁  获能
//     *
//     * @param $box_no
//     * @return bool
//     * @author Fx
//     *
//     */
//    public static function outAreaGetElectric($box_no)
//    {
//        self::playVoice($box_no, self::VIDEO_KEEP_GOING);
//        return self::electricSwitchControl($box_no, '01');
//    }
//
//    public static function bellBike($box_no)
//    {
//        return self::playVoice($box_no, self::VIDEO_BIKE_HERE);
//    }
//
//    /**
//     * 删除缓存
//     * @param $box_no
//     * @param $type
//     * User: Mead
//     */
//    public static function delRedisCache($box_no, $types)
//    {
//        $cacheNames = [];
//        if (is_array($types)) {
//            foreach ($types as $type) {
//                $cacheNames[] = "cache:min:{$type}:{$box_no}";
//            }
//        } else {
//            $cacheNames[] = "cache:min:{$types}:{$box_no}";
//        }
//        if (!count($cacheNames)) return false;
//        Redis::connection()->del($cacheNames);
//    }
//
//
//    /**
//     * 获取序号(msg_id)
//     * @return string
//     * Author: Mead
//     */
//    private static function getMsgId()
//    {
//        $msg_id = str_pad(dechex(rand(0, 65535)), 4, "0", STR_PAD_LEFT);
//        return $msg_id;
//    }
//
//    /**
//     * str2Hex  其他进制转16进制
//     *
//     * @param $str string 需要转的数据
//     * @param $frombase  int 需要转的进制
//     * @param $pad_length int 长度
//     * @return string
//     * @author Fx
//     *
//     */
//    private static function str2Hex($str, $frombase, $pad_length)
//    {
//        return str_pad(base_convert($str, $frombase, 16), $pad_length, 0, STR_PAD_LEFT);
//    }
//
//    /**
//     * char2Hex char 转16进制
//     *
//     * @param $char
//     * @param $pad_length
//     * @return string
//     * @author Fx
//     *
//     */
//    private static function char2Hex($char, $pad_length)
//    {
//        return str_pad(bin2hex($char), $pad_length, 0, STR_PAD_LEFT);
//    }
//
//    /**
//     * 发送数据
//     * @param $box_no
//     * @param $msg
//     * @return bool
//     * User: Mead
//     */
//    private static function send($box_no, $msg)
//    {
//        Gateway::$registerAddress = config('bike.bike_control_register_address');
//        if (Gateway::isUidOnline($box_no)) {
//            Gateway::sendToUid($box_no, '+NNMI,' . hex2bin(str_replace(' ', '', $msg . '0D0A')));
//            return true;
//        }
//        return false;
//    }
//
//    /**
//     * 组装命令
//     * @param $cmd
//     * @param $msgID
//     * @return string
//     * User: Mead
//     */
//    private static function makeSendMsg($cmd, $body, $msg_id = false, $length = false)
//    {
//        if (is_array($body)) {
//            $body = self::arr2arr($body);
//        }
//        if (is_string($body)) {
//            $body = str_split($body, 2);
//        }
//
//
//        if ($length !== false) {
//            $length = str_pad($length, 4, '0', STR_PAD_LEFT);
//        } else {
//            $length = str_pad(dechex(count($body)), 4, '0', STR_PAD_LEFT);
//        }
//
//        if ($msg_id === false) {
//            $msg_id = self::getMsgId();
//        }
//        $header = [
//            $cmd,
//            $msg_id,
//            '00',
//            $length
//        ];
//        $response = self::formatArr($header, $body);
//        $response[] = self::verification($response);
//
//        return self::format(self::$start . implode('', $response));
//    }
//
//    /**
//     * 校检
//     * @param $data
//     * @param $verification
//     * @return bool
//     * Author: Mead
//     */
//    protected static function verification($data)
//    {
//        $a = $b = 0;
//        for ($i = 0; $i < count($data); $i++) {
//            $a = $a + hexdec($data[$i]);
//            $b = $a + $b;
//        }
//        return str_pad(substr(dechex($a), -2), 2, 0, STR_PAD_LEFT) . str_pad(substr(dechex($b), -2), 2, 0, STR_PAD_LEFT);
//    }
//
//    /**
//     * 格式数组
//     * @param $arr
//     * @return array
//     * User: Mead
//     */
//    private static function arr2arr($arr)
//    {
//        $arr = implode('', $arr);
//        return str_split(str_replace(' ', '', $arr), 2);
//    }
//
//    /**
//     * 合并数组
//     * @return array
//     * User: Mead
//     */
//    private static function formatArr()
//    {
//        $args = func_get_args();
//        $arr = '';
//        foreach ($args as $arg) {
//            $arr .= implode('', $arg);
//        }
//        return str_split($arr, 2);
//    }
//
//    /**
//     * 格式字符
//     * @param $str
//     * @return string
//     * User: Mead
//     */
//    private static function format($str)
//    {
//        return strtoupper(implode('', str_split(str_replace(' ', '', $str), 2)));
//    }
//}


/**
 * Created by PhpStorm.
 * User: Mead
 * Date: 2019/9/5
 * Time: 9:36 PM
 */

namespace App\Handlers\Weikemu;


use GatewayClient\Gateway;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class  BikeControl
{
    const VIDEO_RETURN_BIKE = '01';
    const VIDEO_OPEN_LOCK = '02';

    //    还车成功,请规范停车
    const VIDEO_CIVILIZATION = '03';
//   开锁成功
    const VIDEO_POWER_FAILURE = '04';
//    请文明骑行规范停车
    const VIDEO_OFFLINE = '05';
//    车辆已断电请回到服务区
    const VIDEO_ILLEGAL_MOVE = '06';
//    车辆已下线
    const VIDEO_FIND_BIKE = '07';
//    非法移动
    const VIDEO_KEEP_GOING = '08';
//    临停成功将持续计费
    const VIDEO_BIKE_HERE = '09';
//    向着诗和远方我们继续出发吧
    const VIDEO_BATTERY_EDGE = '0A';
//    小喵在这里
    const VIDEO_POWER_CHANGE = '0B';
//    靠近服务区边缘,服务区外将断电 10
    const VIDEO_GO_BEYOND = '0C';
//    换电完成您辛苦了 11
    const VIDEO_NIGHT_SAFETY = '0D';
//    您已出服务区请尽快骑回 12
    const VIDEO_NO_STOPPING = '0E';
//     夜间出行注意安全 13
    const VIDEO_USE_OTHER = '10';
//    当前为禁停区禁止停车 14
    const VIDEO_LOW_POWER = '11';
    // 空 15

    // 小喵生病了试试别的车吧 16
    const VIDEO_OCCUPIED = '12';

    //电量过低 17
    const VIDEO_RESERVED = '13';
    // 主人即将回来试试别的车吧 18
    const VIDEO_WARNING = '14';
    //小猫被预约了试试别的车吧 19
    const VIDEO_NO_STOP_ZONE = '15';
    // (带告警音)请停止偷窃行为 20
    const VIDEO_ALARMED = '16';
    // 您已进入禁停区 21
    const VIDEO_NO_STEALING = '17';
    // 车辆已报警请勿移动 22
    const VIDEO_BOUND = '18';
    //请停止偷窃行为 23
    const VIDEO_FALL = '19';
    // 设备已绑定 24
    const CACHE_KEY = 'cache:select';
    // 小喵摔倒了
    private static $start = '42 44';
    private static $registerAddress = 'node4:3238';

    /**
     * realLocation 3.2.2    实时位置上报参数设置
     *
     * @param $box_no
     * @param string $control 01:实时追踪开启,00:实时追踪关闭
     * @param int $interval 上报间隔  秒 量化值30
     * @param int $continued 持续时长(1-43200) 分钟
     * @return bool
     * @author Fx
     *
     */
    public static function realLocation($box_no, $control = "01", $interval = 1, $continued = 60)
    {
        $cmd = "23";

        $body = [
            self::getMsgId(),
            $control,// 1:实时追踪开启,0:实时追踪关闭
            str_pad(base_convert($interval, 10, 16), 4, 0, STR_PAD_LEFT),//上报间隔
            str_pad(base_convert($continued, 10, 16), 4, 0, STR_PAD_LEFT),//持续时长(1-43200)
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * multipleConfigsSetting 3.2.3    综合配置参数设置
     *
     * @param $box_no
     * @param $arr
     * @return bool
     * @author Fx
     *
     */
    public static function multipleConfigsSetting($box_no, $arr)
    {

        $cmd = "2C";
//        ['ip' => $ip,'port' => $port,'bluetooth_name' => $bluetooth_name,'bluetooth_token' => $bluetooth_token,
//                                                   'is_auto_lock' => $is_auto_lock, 'auto_lock_time' => $auto_lock_time,
//                                                   'is_displacement' => $is_displacement, 'displacement_radius' => $displacement_radius,
//                                                   'is_shock' => $is_shock,
//                                                   'is_temperature' => $is_temperature,'temperature' => $temperature,
//                                                   'is_speeding' => $is_speeding,'speeding'=>$speeding,
//                                                   'motion_position_sampling_interval'=>$motion_position_sampling_interval,
//                                                   'motion_position_reporting_interval'=>$motion_position_reporting_interval,
//                                                   'static_position_reporting_interval'=>$static_position_reporting_interval];
        $ip = $arr['ip'];
        $port = $arr['port'];
        $bluetooth_name = $arr['bluetooth_name']; // 蓝牙名称
        $bluetooth_token = $arr['bluetooth_token']; //蓝牙token
        $is_auto_lock = $arr['is_auto_lock']; // 是否开启自动落锁1:自动落锁开启;0:关闭自动落锁
        $auto_lock_time = str_pad(base_convert($arr['auto_lock_time'], 10, 2), 7, 0, STR_PAD_LEFT); // 自动落锁时长,量化单位1分钟

        $is_displacement = $arr['is_displacement']; // 位移告警开启设置1:位移告警开启;0: 位移告警关闭
        $displacement_radius = str_pad(base_convert($arr['displacement_radius'], 10, 2), 7, 0, STR_PAD_LEFT); // 位移告警半径门限,取值范围0~126,量化单位10米

        $is_shock = $arr['is_shock'];//震动告警开启设置1:震动告警开启,0:震动告警关闭

        $is_temperature = $arr['is_temperature'];//温度告警开启设置。1:温度告警开启;0:温度告警关闭
        $temperature = str_pad(base_convert($arr['temperature'], 10, 2), 7, 0, STR_PAD_LEFT); // 温度告警门限,取值范围0~126,

        $is_speeding = $arr['is_speeding']; // 超速告警开启设置。1:超速告警开启;0:超速告警关闭
        $speeding = str_pad(base_convert($arr['speeding'] * 2, 10, 2), 7, 0, STR_PAD_LEFT); // 超速告警门限 量化单位2km/h,范围 0~126
        $motion_position_sampling_interval = $arr['motion_position_sampling_interval']; // 运动状态,位置采样间隔设置(默认1秒)
        $motion_position_reporting_interval = $arr['motion_position_reporting_interval']; // 运动状态,位置上报间隔设置
        $static_position_reporting_interval = $arr['static_position_reporting_interval']; // 静止状态,位置上报间隔设置

        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            str_pad(base_convert($motion_position_sampling_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置采样间隔设置(默认1秒)
            str_pad(base_convert($motion_position_reporting_interval, 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置上报间隔设置
            str_pad(base_convert($static_position_reporting_interval, 10, 16), 4, 0, STR_PAD_LEFT),// 静止状态,位置上报间隔设置
            str_pad(base_convert($displacement_radius . $is_displacement, 2, 16), 2, 0, STR_PAD_LEFT),// 位移告警
            str_pad(base_convert('0000000' . $is_shock, 2, 16), 2, 0, STR_PAD_LEFT),// 震动告警
            str_pad(base_convert($temperature . $is_temperature, 2, 16), 2, 0, STR_PAD_LEFT),// 温度告警
            str_pad(base_convert($speeding . $is_speeding, 2, 16), 2, 0, STR_PAD_LEFT),// 超速告警
            str_pad(base_convert($auto_lock_time . $is_auto_lock, 2, 16), 2, 0, STR_PAD_LEFT),// 自动落锁
            str_pad(base_convert($port, 10, 16), 4, 0, STR_PAD_LEFT),// 自动落锁
            str_pad(base_convert($ip, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
            str_pad($bluetooth_name, 10, 0, STR_PAD_LEFT),
            str_pad(base_convert($bluetooth_token, 10, 16), 8, 0, STR_PAD_LEFT),// 自动落锁
            '00 00 00 00 00 00'
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, $msg_id);
    }

    public static function setBoxSetting($box_no, $arr)
    {
        $cmd = "2C";
        $auto_lock_time = str_pad(base_convert($arr['auto_lock_time'], 10, 2), 7, 0, STR_PAD_LEFT); // 自动落锁时长,量化单位1分钟

        $ipArr = explode('.', $arr['ip']);
        $ip =
        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            'FF',// 运动状态,位置采样间隔设置(默认1秒)
            str_pad(base_convert($arr['motion_position_reporting_interval'], 10, 16), 2, 0, STR_PAD_LEFT),// 运动状态,位置上报间隔设置
            str_pad(base_convert($arr['static_position_reporting_interval'], 10, 16), 4, 0, STR_PAD_LEFT),// 静止状态,位置上报间隔设置
            'FF',// 位移告警
            'FF',// 震动告警
            'FF',// 温度告警
            'FF',// 超速告警
            str_pad(base_convert($auto_lock_time . '1', 2, 16), 2, 0, STR_PAD_LEFT),// 自动落锁
            'FF FF',
            //str_pad(base_convert($arr['port'], 10, 16), 4, 0, STR_PAD_LEFT),// port
            'FF FF FF FF',
            // str_pad(base_convert($arr['ip'], 10, 16), 8, 0, STR_PAD_LEFT),// ip
            'FF FF FF FF FF FF FF FF FF FF',// 20位
            'FF FF FF FF ',//
            'FF FF FF FF FF FF'
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

//        Log::info($send_msg);
        return self::send($box_no, $send_msg, $msg_id);
    }

    /**
     * reboot  重启中控
     *
     * @param $box_no
     * @param  $reboot string  11:重启升级;01:重启不升级
     * @param $ip   string    重启升级地址(域名或IP地址)
     * @param $port int   重启升级端口号
     * @param $path  string 重启升级路径
     * @param $upFile string 重启升级文件名称
     * @return bool
     * @author Fx
     *
     */
    public static function reboot($box_no, $reboot = "01", $ip, $port, $path, $upFile)
    {
        $cmd = "25";
        $reboot = '000000' . $reboot; // 11:重启升级;01:重启不升级
        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            self::str2Hex($reboot, 2, 8),
            self::char2Hex($ip, 20),
            self::str2Hex($port, 10, 8),
            self::char2Hex($path, 20),
            self::char2Hex($upFile, 20),
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, $msg_id);
    }

    /**
     * str2Hex  其他进制转16进制
     *
     * @param $str string 需要转的数据
     * @param $frombase  int 需要转的进制
     * @param $pad_length int 长度
     * @return string
     * @author Fx
     *
     */
    private static function str2Hex($str, $frombase, $pad_length)
    {
        return str_pad(base_convert($str, $frombase, 16), $pad_length, 0, STR_PAD_LEFT);
    }

    /**
     * char2Hex char 转16进制
     *
     * @param $char
     * @param $pad_length
     * @return string
     * @author Fx
     *
     */
    private static function char2Hex($char, $pad_length)
    {
        return str_pad(bin2hex($char), $pad_length, 0, STR_PAD_LEFT);
    }

    /**
     * nowBikeBatteryMSG  从定位包中获取电量
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function nowBikeBatteryMSG($box_no)
    {
        return self::nowBikeLocation($box_no);
    }

    /**
     * nowBikeLocation 立即定位
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function nowBikeLocation($box_no)
    {
        return self::queryCmd($box_no, '00000001');
    }

    /**
     * queryCmd 3.2.1    查询指令
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function queryCmd($box_no, $str2 = '00111101')
    {
        $cmd = "2B";
        $body = [
            self::getMsgId(),
            str_pad(base_convert($str2, 2, 16), 2, 0, STR_PAD_LEFT)
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * 获取序号(msg_id)
     * @return string
     * Author: Mead
     */
    private static function getMsgId()
    {
        $msg_id = str_pad(dechex(rand(0, 65535)), 4, "0", STR_PAD_LEFT);
        return $msg_id;
    }

    /**
     * 组装命令
     * @param $cmd
     * @param $msgID
     * @return string
     * User: Mead
     */
    private static function makeSendMsg($cmd, $body, $msg_id = false, $length = false)
    {
        if (is_array($body)) {
            $body = self::arr2arr($body);
        }
        if (is_string($body)) {
            $body = str_split($body, 2);
        }


        if ($length !== false) {
            $length = str_pad($length, 4, '0', STR_PAD_LEFT);
        } else {
            $length = str_pad(dechex(count($body)), 4, '0', STR_PAD_LEFT);
        }

        if ($msg_id === false) {
            $msg_id = self::getMsgId();
        }
        $header = [
            $cmd,
            $msg_id,
            '00',
            $length
        ];
        $response = self::formatArr($header, $body);
        $response[] = self::verification($response);

        return self::format(self::$start . implode('', $response));
    }

    /**
     * 格式数组
     * @param $arr
     * @return array
     * User: Mead
     */
    private static function arr2arr($arr)
    {
        $arr = implode('', $arr);
        return str_split(str_replace(' ', '', $arr), 2);
    }

    /**
     * 合并数组
     * @return array
     * User: Mead
     */
    private static function formatArr()
    {
        $args = func_get_args();
        $arr = '';
        foreach ($args as $arg) {
            $arr .= implode('', $arg);
        }
        return str_split($arr, 2);
    }

    /**
     * 校检
     * @param $data
     * @param $verification
     * @return bool
     * Author: Mead
     */
    protected static function verification($data)
    {
        $a = $b = 0;
        for ($i = 0; $i < count($data); $i++) {
            $a = $a + hexdec($data[$i]);
            $b = $a + $b;
        }
        return str_pad(substr(dechex($a), -2), 2, 0, STR_PAD_LEFT) . str_pad(substr(dechex($b), -2), 2, 0, STR_PAD_LEFT);
    }

    /**
     * 格式字符
     * @param $str
     * @return string
     * User: Mead
     */
    private static function format($str)
    {
        return strtoupper(implode('', str_split(str_replace(' ', '', $str), 2)));
    }

    /**
     * 发送数据
     * @param $box_no
     * @param $msg
     * @return bool
     * User: Mead
     */
    private static function send($box_no, $msg, $msg_id = false, $decode = true)
    {
        Gateway::$registerAddress = config('bike.bike_control_register_address');
        if (Gateway::isUidOnline($box_no)) {
            Gateway::sendToUid($box_no, '+NNMI,' . hex2bin(str_replace(' ', '', $msg . '0D0A')));
            if ($msg_id !== false) {
                $redis = Redis::connection();
                $response = false;
                $msg_id = strtolower(substr($msg, 6, 4));

                for ($i = 1; $i <= 40; $i++) {
                    usleep(500000);
                    $data = $redis->get(self::CACHE_KEY . ':' . $box_no . ':' . $msg_id);

                    if ($data) {
                        Log::error('检查key:' . $msg_id);
                        Log::error($data);
                        $response = self::decodeData($data, $decode);
                        break;
                    }
                    if ($i == 20) {
                        //重试一次
                        Gateway::sendToUid($box_no, '+NNMI,' . hex2bin(str_replace(' ', '', $msg . '0D0A')));
                    }
                }
                return $response;
            }
            return true;
        }
        return false;
    }

    /**
     * 解析车辆返回数据
     * @param $data
     * @return bool|mixed
     */
    public static function decodeData($data, $decode = true)
    {
        $array = explode('||', $data);
        if (count($array) !== 2) return false;
        list($type, $value) = $array;
        if (!$decode) return $value;
        switch ($type) {
            case 'string':
                return $value;
                break;
            case 'bool':
                return (boolean)$data;
                break;
            case 'array':
                return json_decode($value);
        }
        return false;
    }

    public static function rebootBox($box_no)
    {
        $cmd = "25";
        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            '01',// 0X02:重启升级;0X01:重启不升级
            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',// ip  20 bytes
            'FF FF FF FF FF FF FF FF FF FF ', // PORT 10 BYTES
            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF', // 重启升级路径
            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF', // 重启升级文件名称
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, $msg_id);
    }

    public static function maxecuspeedToMaxspeedpercent($maxecuspeed = 7)
    {
        $MAXSPEEDPERCENT = 100;
        switch ($maxecuspeed) {
            case 1:
                $MAXSPEEDPERCENT = 70;
                break;
            case 2:
                $MAXSPEEDPERCENT = 75;
                break;
            case 3:
                $MAXSPEEDPERCENT = 80;
                break;
            case 4:
                $MAXSPEEDPERCENT = 85;
                break;
            case 5:
                $MAXSPEEDPERCENT = 90;
                break;
            case 6:
                $MAXSPEEDPERCENT = 95;
                break;
            case 7:
                $MAXSPEEDPERCENT = 100;
                break;
        }
        return $MAXSPEEDPERCENT;
    }

    /**
     * settingVoice  语音设置
     *
     * @param $box_no
     * @param $voice_no
     * @param $ip
     * @param $port
     * @param $path
     * @param $upFile
     * @return bool
     * @author Fx
     *
     */
    public static function settingVoice($box_no, $voice_no, $ip, $port, $path, $upFile)
    {
        $cmd = "2A";
        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            '00',
            self::str2Hex($voice_no, 10, 2),
            self::char2Hex($ip, 20),
            self::str2Hex($port, 10, 8),
            self::char2Hex($path, 20),
            self::char2Hex($upFile, 20),
        ];
        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, $msg_id);
    }

    /**
     * guardSwitch 3.2.7    防盗开关设置
     *
     * @param $box_no
     * @param $control 00:关闭  01:开启
     * @return bool
     * @author Fx
     *
     */
    public static function guardSwitch($box_no, $control)
    {
        $cmd = "2E";
        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            $control
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, $msg_id);
    }

    /**
     * batterySwitch 3.2.8    电池仓开关设置
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function openBatteryLock($box_no)
    {
        $cmd = "2F";
        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            '01',
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * limitSpeed  限速
     *
     * @param $box_no
     * @param $limit int   限速[%]
     * @return bool
     * @author Fx
     *
     */
    public static function limitSpeed($box_no, $limit)
    {
        $cmd = "30";

        $body = [
            self::getMsgId(),
            self::str2Hex($limit, 10, 2),// 限速[%]
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * undervoltageProtection 3.2.10    控制器欠压保护设置
     *
     * @param $box_no
     * @param $limit  int 控制器欠压保护值,量单位1mv
     * @return bool
     * @author Fx
     *
     */
    public static function undervoltageProtection($box_no, $limit)
    {
        $cmd = "31";

        $body = [
            self::getMsgId(),
            self::str2Hex($limit, 10, 4),// 限速[%]
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * currentLimitingProtection 3.2.11    控制器限流保护设置
     *
     * @param $box_no
     * @param $limit int 控制器限流保护值,量化单位1mA
     * @return bool
     * @author Fx
     *
     */
    public static function currentLimitingProtection($box_no, $limit)
    {
        $cmd = "32";
        $body = [
            self::getMsgId(),
            self::str2Hex($limit, 10, 4),//
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * slowReboot 3.2.12    控制器缓启动设置
     *
     * @param $box_no
     * @param $control string 01,缓启动;00,快启动
     * @return bool
     * @author Fx
     *
     */
    public static function slowReboot($box_no, $control)
    {
        $cmd = "33";

        $body = [
            self::getMsgId(),
            $control,
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * lampSwitch 3.2.13    控制器大灯设置
     *
     * @param $box_no
     * @param $control string 01,大灯开;00,大灯关
     * @return bool
     * @author Fx
     *
     */
    public static function lampSwitch($box_no, $control)
    {
        $cmd = "34";

        $body = [
            self::getMsgId(),
            $control,
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * openLock  开锁
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function openLock($box_no)
    {
        $re = self::electricSwitchControl($box_no, '01');
        if ($re) {
            self::orderStatus($box_no, '01');
            self::playVoice($box_no, self::VIDEO_OPEN_LOCK);
            return true;
        }
        return false;
    }

    /**
     * electricSwitchControl  电门控制
     *
     * @param $box_no
     * @param $control 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
     * @return bool
     * @author Fx
     *
     */
    public static function electricSwitchControl($box_no, $control = "01")
    {
        $cmd = "2D";
        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            $control,// 01 电门开启; 00 电门关闭(关闭防盗开关);02 电门关闭(开启防盗开关);
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * orderStatus
     *
     * @param $box_no
     * @param $control string 01:接单开启;00:接单关闭
     * @return bool
     * @author Fx
     *
     */
    public static function orderStatus($box_no, $control)
    {
        $cmd = "35";

        $body = [
            self::getMsgId(),
            $control,
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * 播放语音
     * @param $box_no
     * @return bool
     * User: Mead
     */
    public static function playVoice($box_no, $voice_no, $msg_id = false)
    {
        $cmd = "2A";

        $body = [
            self::getMsgId(),
            '01',
            $voice_no,
            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
            'FF FF FF FF',
            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
            'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF',
        ];

        $send_msg = self::makeSendMsg($cmd, $body);

        return self::send($box_no, $send_msg, false);
    }

    /**
     * closeLock 关锁 (设防)
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function closeLock($box_no)
    {
        $re = self::electricSwitchControl($box_no, '02');
        if ($re) {
            self::orderStatus($box_no, '00');
            self::playVoice($box_no, self::VIDEO_RETURN_BIKE);
            return true;
        }
        return false;
    }

    /**
     * closeLock 临时关锁 (设防)
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function temporaryCloseLock($box_no)
    {
        $re = self::electricSwitchControl($box_no, '02');
        if ($re) {
            self::playVoice($box_no, self::VIDEO_FIND_BIKE);
            return true;
        }
        return false;
    }

    /**
     * temporaryOpnLock  临时开锁
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function temporaryOpnLock($box_no)
    {
        $re = self::electricSwitchControl($box_no, '01');
        if ($re) {
            self::playVoice($box_no, self::VIDEO_KEEP_GOING);
            return true;
        }
        return false;
    }

    /**
     * closeLockNoGuard 关锁 (不设防)  失能
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function outAreaLoseElectric($box_no)
    {
        self::playVoice($box_no, self::VIDEO_GO_BEYOND);
        return self::electricSwitchControl($box_no, '00');
    }

    /**
     * outAreaGetElectric  开锁  获能
     *
     * @param $box_no
     * @return bool
     * @author Fx
     *
     */
    public static function outAreaGetElectric($box_no)
    {
        self::playVoice($box_no, self::VIDEO_KEEP_GOING);
        return self::electricSwitchControl($box_no, '01');
    }

    /**
     * 寻铃
     * @param $box_no
     * @return bool
     * Author: Mead
     */
    public static function bellBike($box_no)
    {
        return self::playVoice($box_no, self::VIDEO_BIKE_HERE, true);
    }

    public static function queryConfig($box_no, $str2 = '00000100')
    {
        $cmd = "2B";

        $msg_id = self::getMsgId();
        $body = [
            $msg_id,
            str_pad(base_convert($str2, 2, 16), 2, 0, STR_PAD_LEFT)
        ];

        $send_msg = self::makeSendMsg($cmd, $body, $msg_id);
        return self::send($box_no, $send_msg, $msg_id);
    }

    public static function getBikeResponse($box_no, $msg_id, $decode = true)
    {
        $redis = Redis::connection();
        $response = false;
        for ($i = 1; $i <= 30; $i++) {
            usleep(500000);
            $data = $redis->get(self::CACHE_KEY . ':' . $box_no . ':' . $msg_id);
            if ($data) {
                $response = self::decodeData($data, $decode);
                break;
            }
        }
        return $response;
    }

    /**
     * 10 进制转  16
     */
    private static function decToHex($hex)
    {
        return str_pad(base_convert($hex, 10, 16), 2, 0, STR_PAD_LEFT);
    }
}