Все начиналось, с некорректно работающее оборудки которая не понимала 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/
Добавить комментарий