#!/usr/bin/php id); define("INTERNAL_USER_USERNAME", $me->username); $mainlog = \mfLoghandler::singleton(); $log = new \mfLog_File(); $log->init(BASEDIR."/var/log/rimo-import.log"); $usage = "Usage: ".$argv[0]." [argument]\n\nAvailable arguments:\n\t--list-rimo-clusters\tLists Clusters returned by Rimo API, then exits\n\t--help\t\t\tLists available arguments\n\nRuns import when no argument is given\n\n"; $command = false; if($argc > 1) { if($argv[1] == "--list-rimo-clusters") { $command = "list-rimo-clusters"; } elseif($argv[1] == "--help") { echo $usage; exit(0); } else { die("Invalid argument.\n\n$usage"); } } //$netowners = ["estmk", "rml"]; $netowners = ["estmk"]; //$netowners = ["rml"]; $apiEdition = "prod"; $starttime = date("Y-m-d.H-i"); foreach($netowners as $apiOwner) { $apiData = TT_RIMO_API_CREDS[$apiOwner][$apiEdition]; $apiUrl = $apiData["url"]; $apiToken = $apiData["key"]; $processType = $apiData["type"]; if(!$apiUrl || !$apiToken) { echo "Api Daten für $apiOwner unvollständig\n"; } $epGetClusters = $apiUrl.RIMO_API_JSON_EP_GET_CLUSTERS; $epGetBuildings = $apiUrl.RIMO_API_JSON_EP_GET_BUILDINGS; $epGetWorkorders = $apiUrl.RIMO_API_JSON_EP_QUERY_WORKORDERS; $epGetService = $apiUrl.RIMO_API_JSON_EP_QUERY_SERVICE; $epGetGeoJsonForBuilding = $apiUrl.RIMO_API_JSON_EP_GET_JSON_FOR_BUILDING; $epGetGeoJsonForCluster = $apiUrl.RIMO_API_JSON_EP_GET_JSON_FOR_CLUSTER; $import_count = 0; $baseParams = ['apiKey' => $apiToken]; $ctxOptsPost = [ 'http' => [ 'method' => 'POST', 'header' => 'accept: application/json' ] ]; $ctxOptsGet = [ 'http' => [ 'method' => 'GET', 'header' => 'accept: application/json' ] ]; $adb = \FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME); /* * Get RIMO Sales Clusters */ $params = $baseParams; $qs = http_build_query($params); $req_url = $epGetClusters."?".$qs; $req_ctx = stream_context_create($ctxOptsGet); //echo $req_url."\n"; $responseText = file_get_contents($req_url, false, $req_ctx); if($responseText === false) { echo "($apiOwner) Error fetching clusters\n"; exit; } $clustersResponse = json_decode($responseText); //var_dump($clustersResponse); //exit; if(!is_object($clustersResponse) || !property_exists($clustersResponse, "item") || !is_array($clustersResponse->item) || !count($clustersResponse->item)) { die("($apiOwner) Invalid GetClusters Response\n"); } foreach($clustersResponse->item as $cluster) { $cluster_rimo_id = $cluster->id; $cluster_name = $cluster->name; //echo "##################################################\n"; if($command == "list-rimo-clusters") { echo "($apiOwner) $cluster_rimo_id | name: ".$cluster->name."; label: ".$cluster->userLabel."\n"; continue; } $adb_netzgebiet = \ADBNetzgebietModel::getFirst(['rimo_id' => $cluster_rimo_id]); if(!$adb_netzgebiet) { //echo "Kein Netzgebiet für Salescluster $cluster_rimo_id (".$cluster->name.")\n"; continue; } $addressErrors = []; if($cluster_rimo_id != "SDIRolloutRegion_97586867201_1711003389") { // stiftingtal continue; } /* * get Cluster Outline Coords */ $params = $baseParams; $params['clusterId'] = $cluster_rimo_id; $qs = http_build_query($params); $req_url = $epGetGeoJsonForCluster."?".$qs; $req_ctx = stream_context_create($ctxOptsGet); //echo $req_url."\n"; $responseText = file_get_contents($req_url, false, $req_ctx); if($responseText === false) { //echo "Error fetching GeoJson for cluster $cluster_rimo_id\n"; continue; } $geodataResponse = json_decode($responseText); if(is_object($geodataResponse) && is_array($geodataResponse->features)) { foreach($geodataResponse->features as $feature) { if(is_object($feature) && property_exists($feature, "geometry") && is_array($feature->geometry->coordinates)) { $coords = $feature->geometry->coordinates[0]; $poly = []; foreach($coords as $coord) { $long = $coord[0]; $lat = $coord[1]; $poly[] = [$lat, $long]; } if($poly) $poly = json_encode($poly); if($adb_netzgebiet->borderpoly != $poly) { $adb_netzgebiet->borderpoly = $poly; $adb_netzgebiet->save(); } } } } $AddressHelper = new ADBAddressHelper\AddressHelper(["log" => $log, "db" => $adb, "netzgebiet" => $adb_netzgebiet]); /* * Get Buildings per SalesCluster */ $params = $baseParams; $params["clusterId"] = $cluster_rimo_id; $qs = http_build_query($params); $req_url = $epGetBuildings."?".$qs; $req_ctx = stream_context_create($ctxOptsGet); //echo $req_url."\n"; $responseText = file_get_contents($req_url, false, $req_ctx); if($responseText === false) { echo "Error fetching Buildings in cluster $cluster_rimo_id (".$cluster->name.")\n"; exit; } $buildingsResponse = json_decode($responseText); $hausnummer_count = 0; $hausnummer_found_count = 0; $homes_count = 0; if(is_object($buildingsResponse) && property_exists($buildingsResponse, "item") && is_array($buildingsResponse->item) && count($buildingsResponse->item)) { foreach($buildingsResponse->item as $building) { //var_dump($building); if($building->buildingType && $building->buildingType->userLabel == "Greenfield") { //echo $building->id.": ignoring Greenfield\n"; continue; } $hausnummer_count++; /* // ignore buildings without units if(!$building->plannedTU) { echo $building->id.": no planned TUs\n"; continue; }*/ $rimo_building_id = $building->id; $hausnummer = $AddressHelper->findUpdateAddressFromRimoBuilding($building); if(!$hausnummer) { //echo "Adresse nicht gefunden: $rimo_building_id\n"; if($AddressHelper->find_address_error) { $addressErrors[] = $AddressHelper->find_address_error; } continue; } $hausnummer_found_count++; $last_unit_num = 0; $existing_units = []; foreach(\ADBWohneinheitModel::search(["hausnummer_id" => $hausnummer->id]) as $unit) { $existing_units[$unit->extref] = $unit; if($last_unit_num < $unit->num) { $last_unit_num++; } } $plannedTU = $building->plannedTU; $to_create_count = $building->plannedTU - count($existing_units); if($plannedTU && $to_create_count > 0) { for($i = 0; $i < $to_create_count; $i++) { $unit = \ADBWohneinheitModel::create([ "hausnummer_id" => $hausnummer->id, "num" => ++$last_unit_num ]); if(!$unit->save()) { die("Error saving new unit\n".print_r($unit, true)); } } } if(!property_exists($building->homes, "item") || !is_array($building->homes->item) | !count($building->homes->item)) { continue; } $rimo_home_count = count($building->homes->item); foreach($building->homes->item as $home) { //print_r($home);//exit; $homes_count++; $home_rimo_id = $home->id; $home_name = $home->name; //echo "$home_rimo_id\n";continue; if(array_key_exists($home_rimo_id, $existing_units)) { $unit = $existing_units[$home_rimo_id]; } else { // find free home without rimo_id $unit = \ADBWohneinheitModel::getFirst(["hausnummer_id" => $hausnummer->id, "extref" => null]); //echo "-- Using free unit\n"; } if(!$unit) { // create unit $unit = \ADBWohneinheitModel::create([ "hausnummer_id" => $hausnummer->id, "extref" => $home_rimo_id, "num" => ++$last_unit_num ]); if(!$unit->save()) { die("Error saving new unit\n".print_r($home, true)); } } if($unit->extref != $home_rimo_id) { $unit->extref = $home_rimo_id; if(!$unit->save()) { die("Error saving new extref on unit\n".print_r($home, true)); } } /* * TODO: Status based on execution-/operational-state */ /* * update FTU data */ $unit_extdata = new \StdClass(); if($unit->external_data) { $extdata = json_decode($unit->external_data); if(is_object($extdata)) { $unit_extdata = $extdata; } } if(is_array($home->ftus->item) && $home->ftus->item[0]) { //echo "in ftu update\n"; $ftu_data = new \StdClass(); $ftu_data->id = $home->ftus->item[0]->id; $ftu_data->name = $home->ftus->item[0]->name; if(!isset($unit_extdata->rimo)) { $unit_extdata->rimo = new \StdClass(); } $unit_extdata->rimo->ftu = $ftu_data; $unit->external_data = json_encode($unit_extdata); if(!$unit->save()) { die("!!! Error saving unit extdata\n".print_f($unit)); } // check OAID if(property_exists($home->ftus->item[0], "oaidObject") && is_object($home->ftus->item[0]->oaidObject) && $home->ftus->item[0]->oaidObject->name) { if($home->ftus->item[0]->oaidObject->name != $unit->oaid) { if(!$unit->oaid) { // assign oaid to home $rimo_oaid = $home->ftus->item[0]->oaidObject->name; $oaid = \OpenAccessIdModel::getFirst(["oaid" => $rimo_oaid]); if(!$oaid) { echo "!!! Home hat fremde OAID: $rimo_oaid (Home ".$unit->id."\n"; } else { $unit->oaid = $rimo_oaid; $oaid->assigned = date("U"); $oaid->adb_wohneinheit_id = $unit->id; $oaid->termination_id = null; $oaid->address = $unit->hausnummer->getAddress(); $oaid->unit_string = (string)$unit; if(!$oaid->exported) { $oaid->exported = date("U"); } if($oaid->export_data) { $exp_data = json_decode($oaid->export_data); } else { $exp_data = new \stdClass(); } if(!property_exists($exp_data, "rimo")) { $exp_data->rimo = new \StdClass(); } $exp_data->rimo->oaid_id = $home->ftus->item[0]->oaidObject->id; $exp_data->rimo->name = $rimo_oaid; $exp_data->rimo->ftu_id = $ftu_data->id; $exp_data->rimo->ftu_name = $ftu_data->name; $exp_data->rimo->ftu_assigned_date = date("U"); $oaid->exported_to = "rmio"; $oaid->export_data = json_encode($exp_data); $oaid->save(); $unit->save(); } } else { // } } } } // get ports from service $params = $baseParams; $params["homeId"] = $home_rimo_id; $qs = http_build_query($params); $req_url = $epGetService."?".$qs; $req_ctx = stream_context_create($ctxOptsGet); //echo $req_url."\n"; $responseText = file_get_contents($req_url, false, $req_ctx); if($responseText === false) { //echo "Error fetching Service for Home $home_rimo_id\n"; continue; } $serviceResponse = json_decode($responseText); if(is_object($serviceResponse) && property_exists($serviceResponse, "item") && is_array($serviceResponse->item) && count($serviceResponse->item)) { foreach($serviceResponse->item as $service) { if($service->masterItem->name != "FTTx Service (red)") continue; if(!is_object($service->portA) || !$service->portA) continue; $fixedDN = $service->portA->fixEndDN; if($fixedDN) { //echo "fixedDn found: $fixedDN\n"; $dn = getServiceDnValues($fixedDN); if(array_key_exists("Shelf", $dn) && array_key_exists("PatchPanel", $dn) && array_key_exists("Port", $dn)) { $sdicluster = null; if(array_key_exists("SDICluster", $dn)) { $sdicluster = $dn['SDICluster']; } $shelf = $dn['Shelf']; $patchpanel = $dn['PatchPanel']; $port = $dn['Port']; if($sdicluster) { $unit->patch_cluster = $sdicluster; $unit->save(); } if($shelf) { $unit->patch_shelf = $shelf; $unit->save(); } if($patchpanel) { $unit->patch_module = $patchpanel; $unit->save(); } if($port) { $unit->patch_port = $port; $unit->save(); } } } } } } //continue; /* * get workorders */ $params = $baseParams; $params["buildingId"] = $rimo_building_id; $qs = http_build_query($params); $req_url = $epGetWorkorders."?".$qs; $req_ctx = stream_context_create($ctxOptsGet); //echo $req_url."\n"; $responseText = file_get_contents($req_url, false, $req_ctx); if($responseText === false) { //echo "Error fetching Workorders for building $rimo_building_id\n"; continue; } $workordersResponse = json_decode($responseText); //print_r($workordersResponse);exit; if(is_object($workordersResponse) && property_exists($workordersResponse, "item") && is_array($workordersResponse->item) && count($workordersResponse->item)) { foreach($workordersResponse->item as $workorder) { $rimo_workorder_id = $workorder->id; $rimo_workorder_name = $workorder->name; $workorder_status = $workorder->state->userLabel; $workorder_home_id = $workorder->home->id; $team_id = (is_array($workorder->teams->item) && count($workorder->teams->item)) ? $workorder->teams->item[0]->id : null; $team_name = (is_array($workorder->teams->item) && count($workorder->teams->item)) ? $workorder->teams->item[0]->name : null; $wo = \RimoWorkorderModel::getFirst(["rimo_id" => $rimo_workorder_id]); if($wo) { //echo "Updating Workorder $rimo_workorder_id ($workorder_home_id)\n"; if($workorder_status != $wo->rimo_status) { $wo->rimo_status = $workorder_status; $wo->save(); } if($team_id != $wo->rimo_team_id) { $wo->rimo_team_id = $team_id; $wo->save(); } if($team_name != $wo->rimo_team_name) { $wo->rimo_team_name = $team_name; $wo->save(); } } if(!$wo) { $wo_home = \ADBWohneinheitModel::getFirst(["extref" => $workorder_home_id]); if(!$wo_home) { //echo "Home zu Workorder $rimo_workorder_id ($workorder_home_id) nicht gefunden\n"; continue; } //echo "Creating Workorder $rimo_workorder_id ($workorder_home_id)\n"; $wo = \RimoWorkorderModel::create([ "adb_wohneinheit_id" => $wo_home->id, "rimo_id" => $rimo_workorder_id, "rimo_name" => $rimo_workorder_name, "rimo_status" => $workorder_status, "rimo_team_id" => $team_id, "rimo_team_name" => $team_name ]); if(!$wo->save()) { echo "Fehler beim Erstellen der RimoWorkorder $rimo_workorder_id ($workorder_home_id)\n"; } } } } /* * Get Geodata */ $params = $baseParams; $params["buildingId"] = $rimo_building_id; $qs = http_build_query($params); $req_url = $epGetGeoJsonForBuilding."?".$qs; $req_ctx = stream_context_create($ctxOptsGet); //echo $req_url."\n"; $responseText = file_get_contents($req_url, false, $req_ctx); if($responseText === false) { //echo "Error fetching Workorders for building $rimo_building_id\n"; continue; } $geodataResponse = json_decode($responseText); //print_r($geodataResponse);exit; if(is_object($geodataResponse)) { if(property_exists($geodataResponse, "homeSection")) { if(property_exists($geodataResponse->homeSection, "features") && is_array($geodataResponse->homeSection->features)) { foreach($geodataResponse->homeSection->features as $feature) { $home_trench = []; foreach($feature->geometry->coordinates as $coords) { $long = $coords[0]; $lat = $coords[1]; $home_trench[] = [$lat, $long]; } if($hausnummer->home_trench != $home_trench) { $hausnummer->home_trench = json_encode($home_trench); $hausnummer->save(); } } } } if(property_exists($geodataResponse, "borderPoint")) { if(property_exists($geodataResponse->borderPoint, "features") && is_array($geodataResponse->borderPoint->features)) { foreach($geodataResponse->borderPoint->features as $feature) { $coords = $feature->geometry->coordinates; //var_dump($coords);exit; $long = $coords[0]; $lat = $coords[1]; if($hausnummer->borderpoint_lat != $lat || $hausnummer->borderpoint_long != $long) { $hausnummer->borderpoint_lat = $lat; $hausnummer->borderpoint_long = $long; $hausnummer->save(); } } } } if(property_exists($geodataResponse, "trenches") && $geodataResponse->trenches->features) { $trenches = []; foreach($geodataResponse->trenches->features as $feature) { $feature_coords = []; //var_dump($feature->geometry->coordinates);exit; foreach($feature->geometry->coordinates as $coords) { $long = $coords[0]; $lat = $coords[1]; $feature_coords[] = [$lat, $long]; } $trenches[] = $feature_coords; } if(count($trenches)) { //var_dump($trenches);exit; $hausnummer->trenches = json_encode($trenches); $hausnummer->save(); } } } } // save address errors if($addressErrors) { $netzname = preg_replace('/[^a-z0-9.-]/i',"_",$adb_netzgebiet->name); $out_folder = dirname(__FILE__)."/output/$starttime"; if(!file_exists($out_folder)) { mkdir($out_folder); } $out_filename = $out_folder."/output-$netzname-$starttime.log"; file_put_contents($out_filename, join("\n", $addressErrors)); } echo "Cluster $cluster_rimo_id ($cluster_name): $hausnummer_count Buildings; $hausnummer_found_count Buildings verarbeitet; $homes_count Homes verarbeitet.\n"; } } } //echo $response; echo "\n"; function getServiceDnValues($dn) { $dn = explode(":", $dn); $fields = []; foreach($dn as $d) { $m = []; if(preg_match('/^([^{]+)\{([^}]+)\}$/',$d, $m)) { if(!$m[1] || !$m[2]) { continue; } $value = $m[1]; $key = $m[2]; if(array_key_exists($key, $fields)) { if(is_array($fields[$key])) { $fields[$key][] = $value; } else { $tmp = $fields[$key]; $fields[$key] = []; $fields[$key][] = $tmp; $fields[$key][] = $value; } } else { $fields[$key] = $value; } } } if(array_key_exists("Shelf", $fields) && is_array($fields['Shelf'])) { $shelf = implode(" ", $fields['Shelf']); $fields['Shelf'] = $shelf; } if(!array_key_exists("PatchPanel", $fields) && array_key_exists("Shelf", $fields)) { $m = []; if(preg_match('/^([MB]\d[^ ]*)\s+([MB]\d[^ ]*)/i', $fields['Shelf'], $m)) { foreach([1,2] as $i) { if(strlen($m[$i])) { $letter = substr(strtoupper($m[$i]), 0, 1); if($letter == "B") { $fields['Shelf'] = $m[$i]; } if($letter == "M") { $fields['PatchPanel'] = $m[$i]; } } } } } return $fields; }