IT/Unified Communications

[FreePBX]Python으로 FreePBX AMI 프로그래밍 테스트 1 (연결, Ping, 종료 흐름)

변화의 물결1 2025. 5. 1. 00:05

 

 

 

안녕하세요.

 

 이전 글에서는 telnet으로 간단하게 연결 확인을 해보았습니다. 그러나 매번 접속해서 수동으로 입력하면서 실행하는 것은 비효율적일 것입니다.

 

 프로그램 언어로 통신하면 순서대로 자동 처리를 할 수 있을 것입니다. 그래서 쉽게 테스트해 볼 수 있는 Python언어를 가지고 FreePBX 전화 시스템과 통신하는 방법인 AMI(Asterisk Manager Interface)에 대해서 확인해 보겠습니다.

 

 AMI가 뭔가요? 하시는 분은 이전 글을 참조 부탁드립니다.

 https://remnant24c1.tistory.com/534

 

 쉽게 말하자면, FreePBX 서버와 통신할 수 있는 약속된 방법입니다. 마치 서버와 채팅하는 것과 비슷합니다.

 


 

1. 준비사항

 

 - PC에 Python 3 설치

 - FreePBX 서버 정보 (IP 주소, AMI 포트 - 보통 5038, AMI 사용자 이름 & 비밀번호)

   이전 글에서 AMI 계정을 만들었다는 전제로 진행합니다. 

 - Windows에서는 Visual Studio, Visual Studio Code, 혹은 메모장 같은 편집툴

 

 

2.  AMI을 사용한 FreePBX에 접속 Python 소스코드 작성

 

 컴퓨터에 ami_connect.py라는 이름으로 새 파일을 만듭니다. 아래 코드를 붙여 넣고, AMI_HOST 등 설정 값 FreePBX 환경에 맞게 수정하고 연결 테스트합니다.

 

 코드 내용은 FreePBX 버전에 따라 조금씩 달라질 수 있으므로 에러가 발생한다면, 코드블록 단위로 실행해서 디버깅하는 작업이 필요합니다.

 

 

1) Python 소스코드 작성

 

# ami_connect.py

import socket 

# ---  FreePBX AMI 설정 ---
AMI_HOST = '192.168.219.110' # FreePBX 서버 IP
AMI_PORT = 5038            # AMI 포트 (기본값)
AMI_USERNAME = 'myuser'    # AMI 사용자 이름
AMI_SECRET = 'myuser'  # AMI 비밀번호
# --- 설정 끝 ---

# --- AMI 응답을 읽는 함수 ---
# 서버가 메시지 하나를 보낼 때 그 끝을 알려주는 표시('\r\n\r\n')가 나올 때까지
# 데이터를 모아서 하나의 문자열로 만들어주는 역할을 합니다.
def read_response(sock):
    data_buffer = b""
    while True:
        chunk = sock.recv(1024)
        if not chunk: # 서버가 연결을 끊으면 문제가 생길 수 있음 (오류처리 없음!)
            print("오류: 서버 연결 끊김 감지됨 (오류처리 없음)")
            return None # 일단 None 반환
        data_buffer += chunk
        if data_buffer.endswith(b'\r\n\r\n'):
            break
    return data_buffer.decode('utf-8', errors='ignore')


def main():
    # --- 메인 프로그램 시작 ---
    print("파이썬 AMI 기본 흐름 시작...")

    # 1. 서버에 연결하기
    print(f"{AMI_HOST}:{AMI_PORT} 에 연결 시도...")
    # 소켓(통신 채널) 생성
    ami_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 서버에 연결!
    ami_socket.connect((AMI_HOST, AMI_PORT))
    print("연결 성공!")

    # 2. 로그인하기
    print("로그인 시도...")
    # 로그인 명령 만들기
    login_cmd = f"Action: Login\r\nUsername: {AMI_USERNAME}\r\nSecret: {AMI_SECRET}\r\nEvents: off\r\n\r\n"
    # 명령어 보내기 (바이트로 변환해서)
    ami_socket.sendall(login_cmd.encode('utf-8'))
    # 로그인 결과 받기
    login_result = read_response(ami_socket)
    print("[서버 응답] 로그인 결과:")
    print(login_result)
    print("로그인 명령 전송 완료.")

    # 3. Ping 명령 보내기
    print("Ping 명령 전송 시도...")
    # Ping 명령 만들기
    ping_cmd = "Action: Ping\r\n\r\n"
    # 명령어 보내기
    ami_socket.sendall(ping_cmd.encode('utf-8'))
    # Ping 결과 받기
    ping_result = read_response(ami_socket)
    print("[서버 응답] Ping 결과:")
    print(ping_result)
    print("Ping 명령 전송 완료.")

    # 4. 로그아웃하기
    print("로그아웃 시도...")
    # 로그아웃 명령 만들기
    logoff_cmd = "Action: Logoff\r\n\r\n"
    # 명령어 보내기
    ami_socket.sendall(logoff_cmd.encode('utf-8'))
    # 로그아웃 결과 받기 (보통 Goodbye 메시지 옴)
    logoff_result = read_response(ami_socket)
    print("[서버 응답] 로그아웃 결과:")
    print(logoff_result)
    print("로그아웃 명령 전송 완료.")

    # 5. 연결 종료하기 (소켓 닫기)
    print("소켓 연결 닫는 중...")
    ami_socket.close()
    print("연결 종료 완료.")

    print("\nPython AMI 기본 흐름 확인 완료!")


if __name__ == "__main__":
    main()

  

 

2) 소스코드 흐름 분석

 

 소스코드는 핵심 흐름 위주로 살펴보겠습니다.

 

 Python 코드를 처음 보면 어려울 수 있는데, 흐름 자체로 보면 소스코드는 간단합니다.

 복잡한 오류 처리(try...except) 없이 순서대로 작업이 진행된다고 보면 됩니다.

 

socket.socket(...) : 네트워크 통신을 위한 소켓(전화기)을 만듭니다.

ami_socket.connect(...) : 만든 소켓을 통해 FreePBX 서버에 연결시도합니다.

 

ami_socket.sendall(...) : 연결 테스트하기 위한 명령어(로그인, Ping, 로그아웃)를 서버에 보냅니다. 보내기 전에 encode('utf-8')로 컴퓨터가 이해하는 바이트 형태로 바꿔줍니다.

 

명령을 보낸 후에는 read_response(ami_socket) 함수로 서버의 응답(로그인 결과, Ping 결과 등)을 읽습니다.

ami_socket.close() : 모든 작업이 끝나면 소켓 연결을 끊습니다.

 

 

3) 실행결과 확인

 

 FreePBX서버에 접속해서 자동으로 로그인하고, Ping 테스트를 하고 로그아웃까지 진행한 결과를 확인할 수 있습니다.

 

 

 

 처음에 접속에 오류가 발생할 수 있습니다. 이유는 서버주소, 포트 설정, 네트워크 끊어지는 문제로 등이 있습니다.

 python이 인터프리터 언어다 보니 오류가 나면 한 줄씩 실행해 가며 디버깅하면 문제없이 테스트할 수 있습니다.

 

 우선 추천하는 것은 telnet으로 ami 접속되는 것을 확인 후 python 코드 테스트하는 것을 추천드립니다.

 위의 소스는 완벽한 소스가 아니기 때문에 read_response()에서 무한정 기다릴 수 있습니다(타임아웃 없음).

 보완해야 할 부분이 많이 있으므로, 참고 정도로 보셨으면 합니다.

 

 

감사합니다.

 

 

 

<참고사이트>

1. [FreePBX] AMI란 무엇이고 접속해 보기

https://remnant24c1.tistory.com/534

2. ettoreleandrotognoli/python-ami

https://github.com/ettoreleandrotognoli/python-ami

3. AMI Libraries and Frameworks

https://docs.asterisk.org/Configuration/Interfaces/Asterisk-Manager-Interface-AMI/AMI-Libraries-and-Frameworks/  

 

 

반응형