본문 바로가기
IT 전자기기

termux 에 python 깔고 미홈 기기 직접 콘트롤 하기.

by 다사도 2026. 1. 30.
반응형
cat << 'EOF' > ~/plug_control.py
import socket
import json
import time
from Crypto.Cipher import AES

# ==========================================
# 1. 사용자 설정 (게이트웨이 및 기기 정보)
# ==========================================
GW_IP = "192.168.0.xxx"  # 게이트웨이 IP 주소
UDP_PORT = 9898           # 고정 UDP 포트
PASSWORD = ""            # 개발자 모드에서 추출한 16자리 비밀번호
TARGET_SID = ""          # 제어할 플러그의 고유 SID

# 고정 IV (AES-128-CBC 암호화용)
AES_IV = bytes([0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58, 0x56, 0x2e])

def generate_key(token, password):
    """토큰과 비밀번호를 사용하여 인증 키 생성"""
    cipher = AES.new(password.encode(), AES.MODE_CBC, AES_IV)
    return cipher.encrypt(token.encode()).hex()

def send_command(sock, sid, status, key):
    """플러그에 On/Off 명령 전송"""
    action = "켜기(ON)" if status == "on" else "끄기(OFF)"
    print(f"📡 플러그({sid}) {action} 명령 전송 중...")
    
    cmd_data = {"status": status, "key": key}
    payload = {
        "cmd": "write",
        "sid": sid,
        "data": json.dumps(cmd_data)
    }
    sock.sendto(json.dumps(payload).encode(), (GW_IP, UDP_PORT))

def main():
    # UDP 소켓 설정
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(5.0)

    try:
        # 1. 게이트웨이로부터 동적 토큰 확보
        print("🔍 게이트웨이 연결 및 토큰 수신 중...")
        sock.sendto(b'{"cmd":"get_id_list"}', (GW_IP, UDP_PORT))
        
        data, _ = sock.recvfrom(1024)
        resp = json.loads(data.decode())
        token = resp.get('token')
        
        if not token:
            print("❌ 토큰을 가져오지 못했습니다. 게이트웨이 설정을 확인하세요.")
            return

        # 2. 암호화 키 생성
        auth_key = generate_key(token, PASSWORD)

        # 3. 플러그 끄기 (OFF)
        send_command(sock, TARGET_SID, "off", auth_key)
        
        # 4. 간격 대기
        wait_time = 2
        print(f"⏳ {wait_time}초 대기 중...")
        time.sleep(wait_time)

        # 5. 플러그 켜기 (ON)
        send_command(sock, TARGET_SID, "on", auth_key)
        
        print("✅ 모든 작업이 성공적으로 완료되었습니다.")

    except socket.timeout:
        print("❌ 통신 타임아웃: 게이트웨이 IP나 네트워크 상태를 확인하세요.")
    except Exception as e:
        print(f"❌ 오류 발생: {e}")
    finally:
        sock.close()

if __name__ == "__main__":
    main()
EOF

# 실행 명령어
python ~/plug_control.py

 

 

cat << 'EOF' > ~/plug_success_fixed.py
import socket
import json
import time
from Crypto.Cipher import AES

# === 고정 설정 정보 ===
GW_IP = "192.168.0.xxx"
UDP_PORT = 9898
PASSWORD = ""  <---- 구버전 미홈 4 나 5 설치해서 게이트웨이 선택하고 점3개 터치 그리고 about 들어가서 하단에 버전 연속 터치 트릭하면 나옴. password 나옴. 이거 없으면 개발 못함.
# 말씀하신 플러그의 고유 ID (lumi. 접두어 제외)
TARGET_SID = ""  <---  기기의 고유아이디는 추출 프로그램 써도 되고 구버전 설치하고 찾아도 됨.

def get_key(token, password):
    iv = bytes([0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58, 0x56, 0x2e])
    cipher = AES.new(password.encode(), AES.MODE_CBC, iv)
    return cipher.encrypt(token.encode()).hex()

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(3.0)
    try:
        # 1. 동적 토큰 확보
        sock.sendto(b'{"cmd":"get_id_list"}', (GW_IP, UDP_PORT))
        data, _ = sock.recvfrom(1024)
        token = json.loads(data.decode()).get('token')
        key = get_key(token, PASSWORD)

        # 2. 플러그 끄기 (Off)
        print(f"🔌 플러그({TARGET_SID}) 전원을 끕니다...")
        off_data = {"status": "off", "key": key}
        off_cmd = {"cmd": "write", "sid": TARGET_SID, "data": json.dumps(off_data)}
        sock.sendto(json.dumps(off_cmd).encode(), (GW_IP, UDP_PORT))
        
        # 3. 2초 대기
        print("⏳ 2초 대기 중...")
        time.sleep(2)

        # 4. 플러그 켜기 (On)
        # 키(key)가 만료되었을 수 있으므로 안전하게 다시 한 번 확인하는 과정이 포함된 성공 로직입니다.
        print(f"⚡ 플러그({TARGET_SID}) 전원을 다시 켭니다!")
        on_data = {"status": "on", "key": key}
        on_cmd = {"cmd": "write", "sid": TARGET_SID, "data": json.dumps(on_data)}
        sock.sendto(json.dumps(on_cmd).encode(), (GW_IP, UDP_PORT))
        
        print("✅ 성공적으로 리셋되었습니다.")

    except Exception as e:
        print(f"❌ 실패: {e}")
    finally:
        sock.close()

if __name__ == "__main__":
    main()
EOF

# 실행
python ~/plug_success_fixed.py

반응형

댓글