stationTaskMaterialBoxService=null; $this->materialBoxService=null; $this->stationService=null; } /** * @param string $modeName '输送线入立架'|'立架出至输送线'|'移动立架内位置'|'缓存架入立架'|'立架出至缓存架' * @param string $fromLocation * @param string $toLocation * @param Collection $taskMaterialBoxes * @param string $groupId * @param int $priority * @param int $isSequenced * @return array */ private function makeJson_move( Collection $taskMaterialBoxes, string $modeName, string $fromLocation='', string $toLocation='', $groupId='' , $priority=10 , $isSequenced=1 ): array { $timestampSuffix = microtime(true); $taskMode=(function()use($modeName){ switch ($modeName){ case '输送线入立架': return 1; case '立架出至输送线': return 2; case '移动立架内位置': return 3; case '缓存架入立架': case '立架出至缓存架': return 6; default: throw new \Exception('发至海柔的移料箱请求,模式不存在'); } })(); $bins=$taskMaterialBoxes->map(function (StationTaskMaterialBox $taskMaterialBox)use($timestampSuffix,$fromLocation,$toLocation){ return [ "taskCode" =>$taskMaterialBox['id'].'_'.$timestampSuffix, "binCode" => $taskMaterialBox['materialBox']['code'], "fromLocCode" => $fromLocation??'', "toLocCode" => $toLocation??'', ]; }); return [[ "taskMode" =>$taskMode, "bins"=>$bins, "groupCode"=>$groupId.'_'.$timestampSuffix, "priority"=>$priority, "sequenceFlag"=>$isSequenced, ]]; } public function fetchGroup($toLocation, Collection $taskMaterialBoxes, $groupIdPrefix=''): bool { LogService::log(__METHOD__,'runMany','波次任务分配6.r5f0:'); LogService::log(__METHOD__,'runMany','波次任务分配6.r5f1:'.json_encode($toLocation).json_encode($taskMaterialBoxes).json_encode($groupIdPrefix)); $dataToPost=$this->makeJson_move( $taskMaterialBoxes, '立架出至输送线', '', $toLocation??'', $groupIdPrefix ); LogService::log(__METHOD__,'runMany','波次任务分配6.r5f2:'.json_encode($dataToPost)); return $this->controlHaiRobot($dataToPost,$taskMaterialBoxes,'立架出至输送线'); } public function moveBin(){ } public function markBinProcessed( $workStation, $binCode, $success, $created_at, $exception, $is_in_plan ): bool { LogService::log('海柔请求','markBinProcessed1.1', ''); $this->instant($this->stationService,'StationService'); $this->instant($this->materialBoxService,'MaterialBoxService'); $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService'); $this->instant($this->stationTaskCommoditiesService,'StationTaskCommodityService'); $this->instant($this->stationTaskBatchService,'StationTaskBatchService'); try{ LogService::log('海柔请求','markBinProcessed1.2', json_encode([$binCode,$success,$exception,$is_in_plan])); if($failed =!$success) throw new ErrorException('海柔任务失败:'.$exception); LogService::log('海柔请求','markBinProcessed1.3', $failed); // if($NotInPlan // =!$is_in_plan) // throw new ErrorException('海柔认为是计划外的料箱:'.$exception); LogService::log('海柔请求','markBinProcessed1.4', '$NotInPlan'); $materialBox= $this->materialBoxService->get(['code'=>$binCode])->first(); LogService::log('海柔请求','markBinProcessed1.5', json_encode($materialBox)); /** @var StationTaskMaterialBox $stationTaskMaterialBox */ $stationTaskMaterialBox =(function()use($materialBox){ return $stationTaskMaterialBox= StationTaskMaterialBox::query() ->where('material_box_id',$materialBox['id']) ->where('created_at','>',Carbon::now()->subDay()) ->whereIn('status',['处理中','待处理','异常','处理队列']) ->orderBy('id','desc') ->first(); })(); LogService::log('海柔请求','markBinProcessed1.6', json_encode($stationTaskMaterialBox)); if(!$stationTaskMaterialBox){ throw new ErrorException($binCode.'该料箱没有安排在处理队列中.'); } LogService::log('海柔请求','markBinProcessed1.7', json_encode($stationTaskMaterialBox)); DB::transaction(function ()use($stationTaskMaterialBox){ $stationTaskMaterialBox_next= $this->stationTaskMaterialBoxService ->processNextQueued($stationTaskMaterialBox); //找到队列中下一个料箱,并标记为处理中 $this->stationTaskCommoditiesService ->markProcessed($stationTaskMaterialBox['stationTaskCommodities']); LogService::log('海柔请求','markBinProcessed1.8', json_encode($stationTaskMaterialBox)); if($stationTaskMaterialBox_next) $this->stationTaskCommoditiesService ->markProcessing($stationTaskMaterialBox_next['stationTaskCommodities']);//因为上边商品任务被标记完成了,所以这里要将队列中找出正在处理的料箱对应的标记为“处理中” $this->stationTaskMaterialBoxService ->markProcessed($stationTaskMaterialBox); $notProcessedBoxTasks = $this->stationTaskMaterialBoxService->getNotProcessedSiblings($stationTaskMaterialBox); if($notProcessedBoxTasks->isEmpty()){ $this->instant($this->stationTaskService,'StationTaskService'); LogService::log('海柔请求','markBinProcessed1.81', json_encode($stationTaskMaterialBox['stationTaskBatch'])); $stationTaskMaterialBox->loadMissing('stationTaskBatch'); $this->stationTaskBatchService->markProcessed($stationTaskMaterialBox['stationTaskBatch']); LogService::log('海柔请求','markBinProcessed1.82', json_encode($stationTaskMaterialBox['stationTaskBatch'])); $this->stationTaskService->markProcessed($stationTaskMaterialBox['stationTask']); } $this->storeBox($stationTaskMaterialBox) ?true :(function(){throw new ErrorException('呼叫机器人回收U型线料箱失败');})(); LogService::log('海柔请求','markBinProcessed1.9', json_encode($stationTaskMaterialBox)); $this->stationService->broadcastBinMonitor($stationTaskMaterialBox['station_id'],$stationTaskMaterialBox['stationTask']); LogService::log('海柔请求','markBinProcessed1.99', json_encode($stationTaskMaterialBox)); }); return true; }catch (\Exception $e){ $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService'); $this->instant($this->materialBoxService,'MaterialBoxService'); $box=$this->materialBoxService->firstOrCreate(['code'=>$binCode]); $stationTaskMaterialBox_toStore= $this->stationTaskMaterialBoxService->create([ 'station_id' => $this->stationService->getStation_byType('立库')['id'], 'material_box_id' => $box['id'], 'status' => '处理中' ] ); $dataToPost=$this->makeJson_move( collect([$stationTaskMaterialBox_toStore]), '输送线入立架', 'BIN-IN1',//TODO:这里应该是动态取得,参考出立架getULineExit()方法,不然不能从站获得对应的出口,而且要改Station的child为children '', $stationTaskMaterialBox_toStore['stationTaskBatch']['id'] ); $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox_toStore]),'输送线入立架'); $stationTaskMaterialBox = $stationTaskMaterialBox_toStore??$materialBox??null; if($stationTaskMaterialBox && get_class($stationTaskMaterialBox)==MaterialBox::class){ $stationTaskMaterialBox = StationTaskMaterialBox::query() ->where('material_box_id',$stationTaskMaterialBox['id']) ->where('status','<>','完成') ->where('created_at','>',now()->format('Y-m-d')) ->first(); } if($stationTaskMaterialBox) $this->stationTaskMaterialBoxService ->excepted($stationTaskMaterialBox); return $e->getMessage(); } } public function storeBox(?StationTaskMaterialBox $stationTaskMaterialBox): bool { LogService::log('海柔请求','putBinToStore1', ''); $this->instant($this->stationService,'StationService'); $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService'); $stationTaskMaterialBox_toStore= $this->stationTaskMaterialBoxService->firstOrCreate([ 'station_id' => $this->stationService->getStation_byType('立库')['id'], 'material_box_id' => $stationTaskMaterialBox['materialBox']['id'], 'status' => '处理中', 'type' => '放', ]); LogService::log('海柔请求','putBinToStore2', json_encode($stationTaskMaterialBox)); $dataToPost=$this->makeJson_move( collect([$stationTaskMaterialBox_toStore]), '输送线入立架', 'BIN-IN1',//TODO:这里应该是动态取得,参考出立架getULineExit()方法,不然不能从站获得对应的出口,而且要改Station的child为children '', $stationTaskMaterialBox['stationTaskBatch']['id'] ); LogService::log('海柔请求','putBinToStore3', json_encode($dataToPost)); $controlSuccess = $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox_toStore]),'输送线入立架'); return $controlSuccess; } /** 缓存架入立架 料箱 任务 * @param StationTaskMaterialBox|null $stationTaskMaterialBox * @param string|null $formLocation * @return bool * @throws ErrorException */ public function putBinToStore_fromCacheShelf(?StationTaskMaterialBox $stationTaskMaterialBox, string $formLocation): bool { LogService::log('海柔请求','putBinToStore_fromCacheShelf1', ''); LogService::log('海柔请求','putBinToStore_fromCacheShelf2', json_encode($stationTaskMaterialBox)); $dataToPost=$this->makeJson_move( collect([$stationTaskMaterialBox]), '缓存架入立架', $formLocation, '' ); LogService::log('海柔请求','putBinToStore_fromCacheShelf3', json_encode($dataToPost)); $controlSuccess = $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox]),'缓存架入立架'); LogService::log('海柔请求','putBinToStore_fromCacheShelf4', 'controlHaiRobot '. json_encode($controlSuccess)); if($controlSuccess){ $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService'); $this->stationTaskMaterialBoxService->set($stationTaskMaterialBox,[ 'status' => '处理中', ]); LogService::log('海柔请求','putBinToStore_fromCacheShelf5', 'controlHaiRobot '. json_encode($stationTaskMaterialBox)); } return $controlSuccess; } public function taskUpdate( // $groupCode, $stationTaskMaterialBox_id, //实际对应传入的字段 taskCode, 这里用料箱任务号做taskCode $updateEventType, //0:task_begin(取货)1:task_end(放货) $status, //0:任务成功1:任务失败 $binCode ):bool{ LogService::log('海柔请求','taskUpdateIn', json_encode([ $stationTaskMaterialBox_id, $updateEventType, $status, $binCode ])); $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService'); try{ if(($failed =$status)==1){ throw new ErrorException('海柔任务失败'); } if($料箱不匹配= !$stationTaskMaterialBox =(function()use($stationTaskMaterialBox_id,$binCode){ $stationTaskMaterialBox=StationTaskMaterialBox::query()->find($id=$stationTaskMaterialBox_id); if($stationTaskMaterialBox['materialBox']['code']==$binCode)return $stationTaskMaterialBox; return null; })()){ throw new ErrorException('发回的料箱和任务号(ID)不匹配:$stationTaskMaterialBox_id:' .$stationTaskMaterialBox_id.' $binCode:'.$binCode. ' '. StationTaskMaterialBox::query() ->where('id', $id=$stationTaskMaterialBox_id) ->get() ->toJson()); } if(($标记已放置= function()use($updateEventType,$stationTaskMaterialBox){ if(($isPut =$updateEventType)==1){ $this->stationTaskMaterialBoxService->markHasPut($stationTaskMaterialBox); return true; }return false; })()) return true; ($标记已取出= function()use($updateEventType,$stationTaskMaterialBox){ if(($isGet =$updateEventType)==0){ $this->stationTaskMaterialBoxService->markHasTaken($stationTaskMaterialBox); } })(); }catch (\Exception $e){ $this->excepted($stationTaskMaterialBox_id, $binCode, $e->getMessage()); return false; } return true; } // public function markHasPut($taskCode,$binCode):bool{ // try{ // //标记料箱进入位置 //// $taskMaterialBoxesService->markDone();// // }catch (\Exception $e){ // switch ($e->getCode()){ // case 'taskBinNotMatch'; // case 'taskGetFailed'; // } // } // // } public function excepted($taskCode='',$binCode='', $msg=''):bool{ try{ throw new ErrorException( "taskCode任务号:$taskCode , binCode箱号:$binCode 海柔运行报错: $msg" ); }catch (\Exception $e){ return true; } } /** * @param array $dataToPost * @return bool */ public function controlHaiRobot(array $dataToPost,Collection $taskMaterialBoxes,$modeName): bool { LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1:'.json_encode($dataToPost)); try{ LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.51:'); $response = Http::post(config('api.haiq.storage.moveBin'), $dataToPost); if(isset($response->json()['code'])&&$response->json()['code']==500) throw new ErrorException('机器人500错误:'.json_encode($response->json())); LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.52:'); LogService::log(__METHOD__,'runMany','波次任务分配6.r5f2c1.53:'.json_encode($response->json())); }catch (\Exception $e){ LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.54:'.json_encode($dataToPost).$e->getMessage()); throw new ErrorException('海柔机器人任务执行失败:'.json_encode($dataToPost).$e->getMessage()); } LogService::log('海柔请求','runMany','波次任务分配6.r5f2c2:'.json_encode($dataToPost)); $errMsg = (function () use ($response) { if ($response->ok()) return ''; $errMsg = '错误: '; if (!$response) { return $errMsg . '没有返回内容,检查连接或目标服务器'; } switch (((string)$response["code"])[0]) { case 5: $errMsg .= '目标服务器代码错误,请联系对方'; break; case 4: $errMsg .= '权限不足以请求资源,请检查对方服务器规范'; break; default: $errMsg .= '出现未知请求错误'; break; } $responseDetails = ' code:' . $response["code"] . ' header:' . $response->body() . ' response:' . json_encode($response->headers()); return $errMsg . $responseDetails; })(); LogService::log('海柔请求','runMany','波次任务分配6.r5f2c3:'.json_encode($errMsg)); LogService::log(__METHOD__, __FUNCTION__, $errMsg ?? '' . '请求:' . json_encode($dataToPost) . '调用堆栈c:' . json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 0, 3)) ); $isSuccess = !$errMsg; $标记料箱状态=(function() use ($taskMaterialBoxes,$modeName){ foreach ($taskMaterialBoxes as $taskMaterialBox){ switch ($modeName){ case '缓存架入立架': case '输送线入立架': case '移动立架内位置': $taskMaterialBox->materialBox['status']='在入库中';break; case '立架出至输送线': case '立架出至缓存架': $taskMaterialBox->materialBox['status']='在出库中';break; default: $taskMaterialBox->materialBox['status']='未知';break; } $taskMaterialBox->materialBox->update(); } })(); return $isSuccess; } }