以下、何となく書いて、何となく、動いた程度。 何となくpythonで書いてみたけど、javaでも書くかな? (気が向いたら)
#!/usr/local/bin/python ## for python 2.7 # -*- coding: utf-8 -*- import asyncore import codecs import netifaces import socket import threading from time import sleep UDP_RESES = [] UDP_PORT = 3610 # for UDP def main(): # 自身のipアドレスを探索 local_ip = UdpSender.find_local_ip_addr() if local_ip == None: return None # echonetのコマンドをudp送信 sender = UdpSender(local_ip) # echonetのコマンド受信用thread recv = UdpReceiverThread() recv.start() echonet_cmd = echonet_cmd_ls() ##echonet機器の一覧取得用コマンド生成 # 224.0.23.0 とは、ECHONET専用のマルチキャストアドレス sender.send_msg("224.0.23.0", echonet_cmd) # 複数機器からレスポンスがある場合があるので、少々、待つ sleep(3) recv.stop() # UDP_RESES に各機器からのレスポンスが、echonet電文とIPで入ってます for udp_res in UDP_RESES: echonet_res = parse_echonet_res(udp_res[0]) print(udp_res) print(echonet_res) # 後はお好きに... def parse_echonet_res(echonet_res): res_cols = [echonet_res[ 0: 4], ## echonetであることの宣言 echonet_res[ 4: 8], ## 自由欄 echonet_res[ 8:14], ## SEOJ(送信元機器) 0ef001=ノード echonet_res[14:20], ## DEOJ(送信先機器) 05ff01=コントローラ echonet_res[20:22], ## 応答code. 71=set 72=get echonet_res[22:24], ## 処理プロパティ数 echonet_res[24:26], ## プロパティ名 d6=自ノードlist. echonet_res[26:28], ## PDC. 後のbyte数 echonet_res[28:36]] ## 0105ff01 = 1個(01)x05ff01 return res_cols ## http://qiita.com/miyazawa_shi/items/725bc5eb6590be72970d def echonet_cmd_ls(): cmd_cols = ["1081", ## echonetであることの宣言 "0000", ## 自由欄 "05ff01", ## SEOJ(送信元機器) 05ff01=コントローラ "0ef001", ## DEOJ(送信先機器) 0ef001=ノード "62", ## 60=set, 61=set(要:応答), 62=get "01", ## 処理プロパティ数 "d6", ## プロパティ名 d6=自ノードlist. ## https://echonet.jp/spec_v112_lite/ にある ## 第2部 ECHONET Lite 通信ミドルウェア仕様の ## 6.11.1 ノードプロファイル詳細規定 参照 "00"] echonet_cmd = "".join(cmd_cols) return echonet_cmd class UdpSender(): def __init__(self, local_ip): self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip)) def send_msg(self, ip,message): decode_hex = codecs.getdecoder("hex_codec") msg = decode_hex( message )[0] self.sock.sendto(msg, (ip, UDP_PORT)) def close(self): self.sock.close() @staticmethod def find_local_ip_addr(find_iface_name=None): for iface_name in netifaces.interfaces(): iface_data = netifaces.ifaddresses(iface_name) af_inet = iface_data.get(netifaces.AF_INET) if not af_inet: continue ip_addr = af_inet[0]["addr"] if find_iface_name == None: return ip_addr elif iface_name == find_iface_name: return ip_addr return None class UdpReceiverThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.server = UdpReceiver() def run(self): asyncore.loop() def stop(self): self.server.close() self.join() class UdpReceiver(asyncore.dispatcher): def __init__(self): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.bind(("0.0.0.0",UDP_PORT)) return def handle_read(self): data = self.recvfrom(4096) encode_hex = codecs.getencoder("hex_codec") global UDP_RESES UDP_RESES.append([encode_hex(str(data[0]))[0], data[1][0]]) return if __name__ == '__main__': main()
↑こう書くと、↓こう出力されます
C:\home\endo\tmp>\Python27\python.exe foo.py ['108100000ef00105ff017201d6040105ff05', '192.168.0.15'] ['1081', '0000', '0ef001', '05ff01', '72', '01', 'd6', '04', '0105ff05']
たまにエラー…windows環境だから?
たまに、次のようなエラーが出力されますので、気が向いたら、調べます。
C:\home\endo\tmp>\Python27\python.exe foo.py Exception in thread Thread-1: Traceback (most recent call last): File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner self.run() File "foo.py", line 106, in run asyncore.loop() File "C:\Python27\lib\asyncore.py", line 216, in loop poll_fun(timeout, map) File "C:\Python27\lib\asyncore.py", line 145, in poll r, w, e = select.select(r, w, e, timeout) error: (10038, '\x83\\\x83P\x83b\x83g\x88\xc8\x8aO\x82\xcc\x82\xe0\x82\xcc\x82\xc9\x91\xce\x82\xb5\x82\xc4\x91\x80\x8d\xec\x82\xf0\x8e\xc0\x8ds\x82\xb5\x82\xe6\x82\xa4\x82\xc6\x82\xb5\x82\xdc\x82\xb5\x82\xbd\x81B')