chakokuのブログ(rev4)

日々のごった煮ブログです

メモ:EchonetLiteのINF_REQ(0x63)をUDP Multicast で送信して受信するPythonサンプル

マイナーすぎるのでほぼ自分用忘備録
仕様:EchonetLiteのINF_REQ(0x63)をUDP Multicastで送信して、同一プログラム内で受信もするPythonサンプルコード(受信側はUDP Unicast/Multicastの両方のパケットが受信可能)
お礼とお詫び:いろんな人のソースを参考に作ったので引用元がもうわからず。サンプルソースを公開してくださった皆様ありがとうございます。ミキシングされてしまい、どれをどう引用したか、もうわかりません。すみません
課題:送信用、受信用2つのUDPソケットを開いていますが、このような実装が正しいのかどうか自信ありません。エラーにはならずに動いてはいる。何をもって正しい実装と言えるのか、判断の根拠が分からない。2つのソケットで同じローカルIPをbindしているけど、、ポートが違うからそれは問題ないのだろうと推測。ポートを共用してはいないので許されるのだろう。。多分。。はぁ。。自信ない。。

#!/usr/bin/python3

import time
import threading
import socket
import config
import parse

def receive_packet(dummy):
    print("------starting receive thread-----")
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind((config.LOCAL_ADDR, config.ECHONET_PORT))
    sock.setsockopt(socket.IPPROTO_IP,
                socket.IP_ADD_MEMBERSHIP,
                socket.inet_aton(config.MULTICAST_GROUP) + socket.inet_aton(config.LOCAL_ADDR))

    msg = None
    msg, address = sock.recvfrom(128)
    print(f"from: {address}")
    parse.dump(msg.hex())
    sock.close()  
    print("------end of receive thread-----")


def ELP_infreq():

    # create socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # bind
    print(f"listen at:{config.LOCAL_ADDR} port:{config.ECHONET_PORT}")
    sock.setsockopt(socket.IPPROTO_IP, 
    		socket.IP_MULTICAST_IF, 
    		socket.inet_aton(config.LOCAL_ADDR))
    p = threading.Thread(target = receive_packet, args = (None, ))
    print(f"multicast:{config.MULTICAST_GROUP} port:{config.ECHONET_PORT}")
    msg = "1081000205FF010EF0016301D600"   # infreq D6(ins list) ask to node prop
    parse.dump(msg)
    msg = bytes.fromhex(msg)
    p.start()
    sock.sendto(msg, (config.MULTICAST_GROUP, config.ECHONET_PORT))
    sock.close()
    
    #receive(sock)
    p.join()

    print("bye")
    

ELP_infreq()

以下実行例

$ ./sendrec_infreq_mul.py
listen at:192.168.10.152 port:3610
multicast:224.0.23.0 port:3610
|10|81|0002|05FF01|0EF001|63(INF_REQ)|01|D6()_00_|
------starting receive thread-----
from: ('192.168.10.150', 49154)
|10|81|0002|0ef001|05ff01|73(INF)|01|d6()_07_0205ff01013009|
------end of receive thread-----
bye

メディアコンバータ*1からINF(0x73)+自ノードインスタンスリスト(0xd6)の返信が得られています。メディアコンバータには、0x5ff01(コントローラ)と、0x013009(エアコン)がぶら下がっている。。と。。

*1:商品名は、Panasonic製の無線ゲートウェイ(メディアコンバータ)型番:CF-TC7B