Как я решал задачу по отключению абонентов HYDRA Billing в BDCOM

от автора

Все начиналось, с некорректно работающее оборудки которая не понимала SNMP запросы, и работать надо было через telnet команды, ну так начнем, для работы с telnet я использовал сторонии класс , честно говор не помню где его скачал, думаю наити что то похожее не проблема

require_once(__DIR__ . '/TelnetClient/TelnetClient.php');

Добавил наши настройки в самый верх файла это будет очень удобно, укажем такие параметры как логин пароль хост к базе данных биллинга гидры (Oracle DB)

Функция Start , будет выполнять запуск второстепенных функции , которые выполнят наш функционал по включения\отключению абонентов в зависимости от положительного баланса или отрицательного

function Start($conf) {    $filelog = new FileLog($conf);   $mac_on_really = [];   $mac_off_really = [];    $hydra = new HydraAPI($conf);   $mac_on =  $hydra->Get_BDCOM_ONOFF(true);   $mac_off =  $hydra->Get_BDCOM_ONOFF(false);      $lines = file($this->conf['bdcom_onoff_file'], FILE_IGNORE_NEW_LINES);             foreach ($mac_on as $mac) {     foreach ($lines as $line) {       $finded = false;       // Ищем наш мак с строке результата       if(strpos($line, $mac)>-1)           {             if(trim($line) === trim("$mac:enable")) { $finded = true; break;  }           }     }      if($finded === false) { $mac_on_really[] = $mac; }   }       foreach ($mac_off as $mac) {     foreach ($lines as $line) {       $finded = false;       // Ищем наш мак с строке результата       if(strpos($line, $mac)>-1)           {             if(trim($line) === trim("$mac:disable")) { $finded = true; break;  }           }     }      if($finded === false) { $mac_off_really[] = $mac; }   }     TelnetOnOFFBDCOM($conf,$mac_on_really, true);   TelnetOnOFFBDCOM($conf,$mac_off_really, false);  }

Функция которая будет включать\выключать устройства BDCOM , создадим объекты классов такие как Filelog — работа с логами, TelnetClient — работа с telnet, используя команды и список мак адресов которые нужно включить\отключить выполним нужные команды запишем результат в файл логов

// Функция которая будет вкл/выкл бдком и записывать значения в фаил function TelnetOnOFFBDCOM($conf,$mac_arr,$onoff = true) { $epon_port = false; $result_onoff = false;  $filelog = new FileLog($conf);  $telnet = new TelnetClient($host, $port); $telnet->connect(); // Логин $telnet->setPrompt('/(ogin|name|word|UserName):.*$/'); $telnet->sendCommand('netadmin', true); // пароль $telnet->setPrompt('/(word|PassWord):.*$/'); $telnet->sendCommand('netadmin', true); $telnet->setPrompt('>'); $telnet->sendCommand('enable', true); $telnet->setPrompt('#'); $telnet->sendCommand('config', true); $telnet->setPrompt('#');  if($onoff) $command = "enable" else $command = "disable";  foreach ($mac_arr as $mac_item) {   // конвертируем мак в нужный формат   $mac = ConvertMacToDelimitier($mac_item,'.');  $telnet->sendCommand('show epon onu-information mac-address '.$mac, true); $telnet->setPrompt('registered'); // получаем ответ ввиде массива для каждои строки $array = $telnet->exec('', true);  foreach($array as $item) {  // если в строке есть искомый мак   if(strpos($item,$mac)>-1)   {     // если есть второе соотвествие   if(strpos($item,'EPON')>-1)     {     $epon_port_arr = explode(':',$item);     // получаем EPON порт     $epon_port = trim($epon_port_arr[0]).':'.trim(substr($epon_port_arr[1], 0,3));     break;     }   }  } // конец перебора ответа  $telnet->sendCommand("", true);  if($epon_port)  {   $port = str_replace("EPON",'',$epon_port);   $telnet->sendCommand("interface epON ".$port);   $telnet->setPrompt('#');   $telnet->sendCommand("epon onu catv $command", true);   $telnet->setPrompt('/');   $result_onoff = true;  } // если результат успешно то запишем результат в фаил if($result_onoff) {    $str = ;     // ищем результат в фаиле    $data = $filelog->GetStrFromFile($mac);    if($data)    {    $result =  $data['data'];    $line = $data['line'];    // делаем замену строки    $filelog->SetReplaceStr($line, $mac.':'.$command);    }    else    {     // добавляем новую строку     $filelog->SetRewriteFile($mac.':'.$command);      }    $log_str = date("Y-m-d h:i:s")." mac ".$mac.':'.$command;    $filelog->SetRewriteLogFile($log_str);     }  } // перебор нескольких мак адресов  $telnet->sendCommand('exit', true);  $telnet->disconnect();  }

Напишем класс который будет работать с логами

class FileLog {    public $conf;     function __construct($conf)    {     $this->conf = $conf;    }      function SetRewriteLogFile($str)    {     $fhandle = fopen($this->conf['log_file_name'],"w");     fwrite($fhandle,$content);     fclose($fhandle);    }     function SetRewriteFile($str)    {     $fhandle = fopen($this->conf['bdcom_onoff_file'],"w");     fwrite($fhandle,$content);     fclose($fhandle);    }     function SetAddStringFile($str)    {     $fp = fopen($this->conf['log_file_name'], 'a+'); //- а+ добавляет новые данные после существующих     fwrite($fp, $str."\r\n"); //а "r\n\" - вставляет их каждый рас с новой строки     fclose($fp);    }     // Прочитать строку в которои есть этот мак    function GetStrFromFile($mac)    {                 $result = false;             $line = 0;             $fp = @fopen($this->conf['bdcom_onoff_file'], "r");         if ($fp) {             while (($buffer = fgets($fp, 4096)) !== false) {                if(strpos($buffer, $mac) !== false) {  $result['data'] = explode(':', $buffer); $result['line'] = $line; break;  }                $line = $line +1;             }                         if (!feof($fp)) {                 echo "Ошибка: fgets() неожиданно потерпел неудачу\n";             }             fclose($fp);         }         return $result;    }

Напишем класс который будет работать с биллингом Hydra (Oracle DB), наверное единственная функция в классе которая будет иметь интерес Get_BDCOM_ONOFF — позволяет используя SQL запрос получить нам должников или абонентов с положительным балансом

class HydraAPI {  public $conn;   function __construct($conf)     {         try {             $conn = @oci_connect($conf['hydra_user'], $conf['hydra_pwd'], $conf['hydra_host'] . '/' . $conf['hydra_db'], 'AL32UTF8');             if (!$conn) {                 $e = oci_error();                // trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);             }              $this->conn = $conn;         }catch(Exception $e) {}      }     public function Get_BDCOM_ONOFF($onoff = true)     {         try{                          if($onoff) { $balance_str = '>'; } else { $balance_str = '<'; }              $query = "SELECT DISTINCT CONCAT('https://95.182.107.243:8000/subjects/persons/edit/',OS.N_SUBJECT_ID) URL,        SU.VC_BASE_SUBJECT_NAME,        OV.VC_VALUE,        -- Значение         g.vc_name,        SU.N_SUBJ_STATE_ID FROM   SI_V_OBJ_SUBJECTS   OS, si_subj_accounts sa, SI_V_USERS SU,        SR_GOODS G,        SI_OBJ_OBJECTS SOO,        SI_V_OBJECTS_SIMPLE O      LEFT JOIN SI_V_OBJ_VALUES  OV on (OV.N_GOOD_VALUE_TYPE_ID in (55898801,56112401) AND  O.N_OBJECT_ID = OV.N_OBJECT_ID  )    WHERE  OS.N_OBJECT_ID  = O.N_OBJECT_ID  AND    g.n_good_id = o.n_good_id AND SU.N_CUSTOMER_ID = OS.N_SUBJECT_ID AND SU.N_SUBJ_STATE_ID = 2011 AND sa.n_subject_id= os.n_subject_id AND SI_USERS_PKG_S.GET_ACCOUNT_BALANCE_SUM(sa.n_account_id) $balance_str 0 AND OV.VC_VALUE IS NOT NULL and exists (Select * from si_v_subscriptions ss where ss.n_customer_id = su.n_customer_id and ss.n_service_id in (54614801) and ss.c_fl_closed='N'  ) AND soo.n_object_id = o.n_object_id   AND soo.n_bind_object_id in (SELECT obj2.n_object_id FROM SI_V_OBJECTS OBJ2 WHERE obj2.n_good_id=56105201 and obj2.n_object_id = 56107601)";                    $stid = oci_parse($this->conn, $query);             oci_execute($stid);              while ($row = oci_fetch_array($stid, OCI_ASSOC + OCI_RETURN_NULLS)) {              $MAC = $row['VC_VALUE'];               $result[] = $MAC;             }                  return $result;              }catch (\Exception $e){ return false;}       }    }


ссылка на оригинал статьи https://habr.com/ru/post/685664/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *