123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- <?php
- namespace App\Server;
- use AlibabaCloud\Iot\V20180120\RRpc;
- use App\Model\DeliverInfo;
- use App\Model\DeviceInfo;
- use App\Model\SystemConfig;
- use App\Model\WaringMessage;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Cache;
- class DeviceServer
- {
- private $conf;
- private $property;
- private $blueProperty;
- const CLOSE = 0;
- const OPEN = 1;
- const AGENTOPEN = 2;
- const AGENTCLOSE = 3;
- public function __construct()
- {
- $this->property = [
- 'box1up' => 'box1',
- 'box2up' => 'box2',
- 'box3up' => 'box3',
- 'box4up' => 'box4',
- 'box5up' => 'box5',
- 'box6up' => 'box6',
- 'Software_Version' => 'version',
- 'IMEI' => 'imei',
- // 'GeoLocation' => 'location',
- 'MagDoorSwitch' => 'lock_switch',
- 'RodSwitch' => 'deliver_lock_switch',
- 'RunningState' => 'runningStatus',
- 'Weight' => 'device_weight',
- 'RestCapacity' => 'rest_capacity',
- ];
- $this->blueProperty = [
- 'CurrentTemperature' => 'device_tem',
- 'IMEI' => 'imei',
- //'GeoLocation' => 'location',
- 'MagDoorSwitch' => 'lock_switch',
- 'RodSwitch' => 'deliver_lock_switch',
- 'RunningState' => 'runningStatus',
- 'Weight' => 'device_weight',
- 'RestCapacity' => 'rest_capacity',
- ];
- $this->conf = SystemConfig::get('ali_config');
- }
- /**
- * 刷新所有设备列表
- * @return string|bool
- */
- public function refreshList()
- {
- $conf = $this->conf;
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- if (!isset($conf['productKey']) || empty($conf['productKey'])) {
- return '请先配置阿里云产品识别码';
- }
- $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- $list = $ali->getDeviceList($conf['productKey'], 100);
- $deviceList = $list['Data']['DeviceInfo'];
- if ($list['Page'] < $list['PageCount']) {
- for ($i = ($list['Page'] + 1); $i <= $list['PageCount']; $i++) {
- $list = $ali->getDeviceList($conf['productKey'], 100, $i);
- $deviceList = array_merge($deviceList, $list['Data']['DeviceInfo']);
- }
- }
- foreach ($deviceList as $key => $val) {
- $check = DeviceInfo::where([['device_name', $val['DeviceName']], ['product_key', $val['ProductKey']]])
- ->orWhere('iot_id', $val['IotId'])->first(['id', 'status']);
- $status = 0;
- switch ($val['DeviceStatus']) {
- case 'ONLINE':
- $status = DeviceInfo::ONLINE;
- break;
- case 'OFFLINE':
- $status = DeviceInfo::OFFLINE;
- break;
- case 'UNACTIVE':
- $status = DeviceInfo::UNACTIVE;
- break;
- case 'DISABLE':
- $status = DeviceInfo::DISABLE;
- break;
- }
- if ($check) {
- $check->status = $status;
- $check->save();
- } else {
- $create = [
- 'status' => $status,
- 'iot_id' => $val['IotId'],
- 'product_key' => $val['ProductKey'],
- 'device_secret' => $val['DeviceSecret'],
- 'device_name' => $val['DeviceName'],
- ];
- if ($status != 3) {
- DeviceInfo::insert($create);
- }
- }
- $this->refreshDevice($val['IotId']);
- }
- return true;
- }
- /**
- * 刷新设备属性
- * @param String $iot_id
- * @return bool|string|array
- */
- public function refreshDevice(string $iot_id)
- {
- $conf = $this->conf;
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- $deviceProperty = $ali->getDeviceProperty($iot_id);
- Log::info("设备数据刷新[1]:" . json_encode($deviceProperty));
- if (isset($deviceProperty['Success']) && $deviceProperty['Success']) {
- $data = [];
- foreach ($deviceProperty['Data']['List']['PropertyStatusInfo'] as $index => $item) {
- if (isset($this->property[$item['Identifier']])) {
- if (isset($item['Value'])) {
- $data[$this->property[$item['Identifier']]] = $item['Value'];
- } else {
- return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
- }
- }
- }
- if (empty($data)) {
- return ['data' => ['ErrorMessage' => '未获取到设备属性'], 'code' => 3];
- }
- //修复
- // if ($data['deliver_lock_switch'] == 1) {
- // return ['data' => ['ErrorMessage' => '当前设备已开启,请等待'], 'code' => '2'];
- // }
- /* if (isset($data['location'])) {
- $location = json_decode($data['location'], true);
- $data['device_latitude'] = $location['latitude'];
- $data['device_longitude'] = $location['longitude'];
- unset($data['location']);
- }*/
- /*if ($data['rest_capacity'] == 0) {
- $data['status'] = DeviceInfo::MAX;
- } else {
- $data['status'] = DeviceInfo::WELL;
- }*/
- $insert['device_item'] = $data['device_tem'];
- $insert['imei'] = $data['imei'];
- if ($data['device_tem'] >= 80) {
- $id = DeviceInfo::where('iot_id', $iot_id)->first(['id'])->id;
- // Log::info("设备温度【{$id}】:{$data['device_tem']}" );
- // WaringMessage::temWaring($id);
- }
- $res = DeviceInfo::where('iot_id', $iot_id)->update($insert);
- if (!$res) {
- Log::info('设备数据刷新[2]:' . json_encode($data));
- }
- return ['data' => $data, 'code' => '0'];
- } else {
- return ['data' => $deviceProperty, 'code' => 1];
- }
- }
- /**
- * 获取设备属性
- * @param String $iot_id
- * @return bool|string|array
- */
- public function getProperty(string $iot_id)
- {
- $conf = $this->conf;
- //Todo 全局 两个if合并
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- $deviceProperty = $ali->getDeviceProperty($iot_id);
- // dd($deviceProperty);
- if (isset($deviceProperty['Success']) && $deviceProperty['Success']) {
- $data = [];
- foreach ($deviceProperty['Data']['List']['PropertyStatusInfo'] as $index => $item) {
- if (isset($this->property[$item['Identifier']])) {
- if (isset($item['Value'])) {
- $data[$this->property[$item['Identifier']]] = $item['Value'];
- } else {
- $data[$this->property[$item['Identifier']]] = '';
- // return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
- }
- }
- }
- if (empty($data)) {
- return ['data' => ['ErrorMessage' => '未获取到设备属性'], 'code' => 3];
- }
- /*if (isset($data['location'])) {
- $location = json_decode($data['location'], true);
- $data['device_latitude'] = $location['latitude'];
- $data['device_longitude'] = $location['longitude'];
- unset($data['location']);
- }*/
- /*if ($data['rest_capacity'] == 0) {
- $data['status'] = DeviceInfo::MAX;
- } else {
- $data['status'] = DeviceInfo::WELL;
- }*/
- return ['data' => $data, 'code' => '0'];
- } else {
- return ['data' => $deviceProperty, 'code' => 1];
- }
- }
- //蓝牙链接 传输加密数据
- public function getDecodeProperty(string $base64_data, string $iot_id)
- {
- Log::info($base64_data);
- $conf = $this->conf;
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- $dataDecode = ToolServer::decode($base64_data, '1234567890123456');
- //$dataDecode = json_decode($base64_data, true);
- Log::info("蓝牙设备数据刷新:" . json_encode($dataDecode));
- $data = [];
- if (!$dataDecode["P"]) {
- return ['message' => '未获取到设备属性', 'code' => 3];
- }
- $updateIotData = [];
- foreach ($dataDecode["P"] as $index => $item) {
- if (isset($this->property[$item['I']])) {
- if (isset($item['V'])) {
- $data[$this->property[$item['I']]] = $item['V'];
- $updateIotData[$item['I']] = $item['V'];
- } else {
- return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
- }
- }
- }
- if (empty($data)) {
- return ['message' => '未获取到设备属性', 'code' => 3];
- }
- $iotService = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- $resUpload = $iotService->setDeviceProperty($iot_id, $updateIotData);
- /*if (!$resUpload['Success']) {
- return ['message' => '设备数据上报物联网失败', 'code' => 4];
- }*/
- if ($data['device_tem'] >= 80) {
- $id = DeviceInfo::where('iot_id', $iot_id)->first(['id'])->id;
- WaringMessage::temWaring($id);
- }
- $res = DeviceInfo::where('iot_id', $iot_id)->update($data);
- if (!$res) {
- Log::info('设备数据刷新[3]:' . json_encode($data));
- }
- return ['data' => $data, 'code' => '0'];
- }
- public function getBase64Property(string $base64_data)
- {
- $dataDecode = json_decode(base64_decode($base64_data), true);
- // Log::debug($dataDecode);
- if ( empty($dataDecode)|| !is_array($dataDecode) || !isset($dataDecode['identifier']) ) {
- return true;
- }
- if ($dataDecode['identifier'] == 'errorEvent') {
- $id = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id'])->id;
- WaringMessage::normalWarning($id, $dataDecode['value']['errorEvent'], WaringMessage::ALARM);
- return true;
- }
- if ($dataDecode['identifier'] == 'warnEvent') {
- $device = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id', 'device_comment']);
- $last = WaringMessage::where([['no', $device->id], ['message', $dataDecode['value']['warnEvent']], ['type', WaringMessage::WARN]])->first(['created_at']);
- $mobile = SystemConfig::get('system_config', 'admin_mobile', 18981831779);
- if ($mobile && (!$last || ($last && strtotime($last->created_at) + 1800 <= time()))) {
- $type = SystemConfig::get('sms_config', 'sms_type', 'AliSmsServer');
- $template = SystemConfig::get('ali_config', 'sms', '');
- $template = json_decode($template, true);
- if ($template['DeviceTmpId'] && $template['sign']) {
- $type = '\App\Server\Sms\\' . $type;
- $sms = new SmsServer(new $type($mobile, $template['DeviceTmpId'], $template['sign'], ['deviceId' => $device->id, 'deviceName' => $device->device_comment, 'warnInfo' => $dataDecode['value']['warnEvent']]));
- $sms->send();
- }
- }
- WaringMessage::normalWarning($device->id, $dataDecode['value']['warnEvent'], WaringMessage::WARN);
- return true;
- }
- if ($dataDecode['identifier'] == 'commoneEvent') {
- //toDO 开/关门
- $device = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id']);
- if(!$device){
- return true;
- }
- $order = DeliverInfo::where('device_id', $device->id)->orderBy('id', 'Desc')->first();
- //优化关门统一走回调
- if(!$order || $order->status != DeliverInfo::UNFINISHED){
- return true;
- }
- Log::info('Cache:' . 'device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId']);
- //处理设备发送重复消息
- if (Cache::has('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'])) {
- Log::info('关门回调通知重复消息:' .$dataDecode['requestId']);
- return true;
- }
- if($dataDecode['value']['action']=='open') {
- //开门回调通知
- Log::info('开门回调通知:' . json_encode($dataDecode));
- $order->open_weight = $dataDecode['value']['weight'];
- $order->save();
- Cache::put('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'], $dataDecode['requestId'], 3600);
- return true;
- }
- if($dataDecode['value']['action']=='close'){
- //关门回调通知
- Log::info('关门回调通知:' . json_encode($dataDecode));
- $close_weight = $dataDecode['value']['weight'];
- $weight = $close_weight - $order->open_weight;
- $order->close_weight = $close_weight;
- $order->weight = $weight;
- $order->finished_at = date('Y-m-d H:i:s');
- Log::info('关门回调变化重量:'.$weight);
- Log::info('关门回调关门重量:'.$close_weight);
- Log::info('关门回调获得金额:'.$order->money);
- Log::info('关门回调变化重量:'.($weight <= 0));
- Cache::forget('deviceUse_' . $device->id);
- $fetch_price= SystemConfig::get('system_config', 'fetch_per_g', '0.1');
- $price = SystemConfig::get('system_config', 'put_per_g', '0.06');
- //如果有小区加个就取小区价格
- $deviceInfo = DeviceInfo::with('communities')->where(['id'=>$order['device_id']])->first();
- if(!empty($deviceInfo->communities)) {
- if(!empty($deviceInfo->communities->put_per_g)) $price = $deviceInfo->communities->put_per_g;
- if(!empty($deviceInfo->communities->fetch_per_g)) $fetch_price = $deviceInfo->communities->fetch_per_g;
- }
- $order->deliver_price = $price;
- $order->transport_price = $fetch_price;
- if ($weight <= 0) {
- $order->status=DeliverInfo::LOSS;
- $order->income = 0;
- if($weight < -5000){
- $order->status=DeliverInfo::UNNORMAL;
- WaringMessage::deliverWarning($order->no);
- }
- $order->save();
- Log::info('关门回调失效订单:' . json_encode($order));
- Cache::put('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'], $dataDecode['requestId'], 3600);
- return true;
- }
- $start = date('Y') . '-' . date('m') . '-' . date('d') . ' 00:00:00';
- $checkCount = DeliverInfo::where([['user_id', $order->user_id], ['status', DeliverInfo::SUCCESS]])
- ->where('created_at', '>', $start)->count();
- $deliverLimit = SystemConfig::get('system_config', 'deliver_limit', 10);
- $deliverWeight = SystemConfig::get('system_config', 'deliver_weight', 0);
- //To Do 地区价格计算公式
- Log::info('筛选时间:' . $start);
- Log::info('投递次数:' . $checkCount);
- Log::info('投递限制:' . $deliverLimit);
- Log::info('地区价格:' . $price);
- if (($deliverWeight != 0 && $weight > $deliverWeight) || $checkCount > $deliverLimit) {
- $order->status = DeliverInfo::WAIT_CHECK;
- } else {
- $order->status = DeliverInfo::SUCCESS;
- }
- $order->money = $price*$weight;
- $order->income = ($fetch_price - $price)*$weight;
- if ($order->save()) {
- Cache::put('device-msg-'.$dataDecode['iotId'].'-'.$dataDecode['requestId'], $dataDecode['requestId'], 3600);
- return true;
- } else {
- return false;
- }
- }
- }
- if (isset($dataDecode['items'])) {
- $property = $dataDecode['items'];
- $data = [];
- if (!$property) {
- return ['message' => '未获取到设备属性', 'code' => 3];
- }
- foreach ($property as $index => $item) {
- if (isset($this->property[$index])) {
- if (isset($item['value'])) {
- $data[$this->property[$index]] = $item['value'];
- } else {
- return ['data' => ['ErrorMessage' => "请检查设备属性[{$item['Identifier']}]是否初始化"], 'code' => 4];
- }
- }
- }
- if (empty($data)) {
- return ['message' => '未获取到设备属性', 'code' => 3];
- }
- if ($data['device_tem'] >= 80) {
- $id = DeviceInfo::where('iot_id', $dataDecode['iotId'])->first(['id'])->id;
- WaringMessage::temWaring($id);
- }
- $res = DeviceInfo::where('iot_id', $dataDecode['iotId'])->update($data);
- $this->getDeviceStatus($dataDecode['iotId']);
- if (!$res) {
- Log::info('设备数据刷新[4]:' . json_encode($data));
- }
- Log::info('success');
- return ['data' => $data, 'code' => '0'];
- }
- return true;
- }
- public function getDeviceStatus($iotId)
- {
- $conf = $this->conf;
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- if (!isset($conf['productKey']) || empty($conf['productKey'])) {
- return '请先配置阿里云产品识别码';
- }
- $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- $res = $ali->GetDeviceStatus($iotId);
- if ($res['Success'] == true) {
- $check = DeviceInfo::Where('iot_id', $iotId)->first(['status']);
- $status = 0;
- switch ($res['Data']['Status']) {
- case 'ONLINE':
- $status = DeviceInfo::ONLINE;
- break;
- case 'OFFLINE':
- $status = DeviceInfo::OFFLINE;
- break;
- case 'UNACTIVE':
- $status = DeviceInfo::UNACTIVE;
- break;
- case 'DISABLE':
- $status = DeviceInfo::DISABLE;
- break;
- }
- ////// dd($val);
- $check->status = $status;
- $check->save();
- return $status;
- } else {
- return 'fail';
- }
- }
- /**
- * 启用和禁用
- * @param String $iot_id
- * @param int $state AliYunIotServer::ENABLE
- * @return array|string
- */
- public function switchDevice(string $iot_id, int $state = AliYunIotServer::ENABLE)
- {
- $conf = $this->conf;
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- $res = $ali->switchDevice($state, $iot_id);
- if (isset($res['Success']) && $res['Success']) {
- if ($state == AliYunIotServer::ENABLE) {
- $state = 0;
- } else {
- $state = 2;
- }
- DeviceInfo::where('iot_id', $iot_id)->update(['status' => $state]);
- return 'success';
- } else {
- return $res['ErrorMessage'];
- }
- }
- /** 投递门/收运门 开关
- * @param string $iot_id
- * @param int $mode
- * @return string
- */
- public function doorOperation(string $iot_id, int $mode = self::OPEN)
- {
- $conf = $this->conf;
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- if ($mode == self::OPEN) {
- $identifier = 'open1';
- } else if ($mode == self::CLOSE) {
- $identifier = 'close1';
- } else if ($mode == self::AGENTOPEN) {
- $identifier = 'RemoteAgentOpen';
- } else if ($mode == self::AGENTCLOSE) {
- $identifier = 'RemoteAgentClose';
- }
- $args = (object)[];
- $res = $ali->invokeThingService($iot_id, $identifier, $args);
- Log::info('doorOperation 参数:'. $iot_id .' '. $mode .'返回数据:'.json_encode($res));
- if (isset($res['Success']) && $res['Success']) {
- DeviceInfo::where('iot_id', $iot_id)->update(['deliver_lock_switch' => $mode]);
- return 'success';
- } else {
- return $res['ErrorMessage'];
- }
- }
- /** 下发锁协议
- * @param string $device_name 设备名称
- * @param string $rules 下发规则
- **/
- public function sendMsg(string $device_name, string $rules)
- {
- $conf = $this->conf;
- if (!isset($conf['appSecret']) || empty($conf['appSecret'])) {
- return '请先配置阿里云app秘钥';
- }
- if (!isset($conf['appKey']) || empty($conf['appKey'])) {
- return '请先配置阿里云appKey';
- }
- $ali = new AliYunIotServer($conf['appKey'], $conf['appSecret']);
- $args['Action'] = "Pub";
- $args['DeviceName'] = $device_name;
- $args['ProductKey'] = 'a15yVIP0Onl';
- $args['MessageContent'] = base64_encode($rules);
- $args['TopicFullName'] = "/a15yVIP0Onl/{$device_name}/user/get";
- // $args['RequestBase64Byte'] = base64_encode($rules);
- // $args['Timeout'] = 7000;
- // $args['Topic'] = "/a15yVIP0Onl/{$device_name}/user/get";
- $data = $ali->RRpc($args);
- return $data;
- }
- }
|