読者です 読者をやめる 読者になる 読者になる

ECHONETLite通信周り

ECHONETLite Python

コード

# coding:utf8
# python3.4.4

from socket import *
from time import sleep
from contextlib import closing
from threading import Thread
from binascii import hexlify, unhexlify

class ELCliant:
    def __init__(self):
        self.ip = self.get_ip()
        self.el_port = 3610
        self.el_group = '224.0.23.0'
        self.bufsize = 4096

        self.flag = True
        self.receiver_isalive = False

    #ローカルIPの取得
    def get_ip(self):
        with closing(socket(AF_INET, SOCK_DGRAM)) as sock:
            sock.connect(('8.8.8.8', 80))
            ip = sock.getsockname()[0]
        return ip

    # str -> hex
    def str2hex(self, str_):
        return hexlify(str_.encode('utf8'))

    # hex -> str
    def hex2str(self, hex_):
        return unhexlify(hex_).decode('utf8')

    #ユニキャスト送信
    def send(self, addr, code):
        b_code = self.str2hex(code)
        with closing(socket(AF_INET, SOCK_DGRAM)) as sock:
            sock.sendto(b_code, (addr, self.el_port))
        return 1

    #マルチキャスト送信
    def multi_send(self, code):
        b_code = self.str2hex(code)
        with closing(socket(AF_INET, SOCK_DGRAM)) as sock:
            sock.setsockopt(IPPROTO_IP, IP_MULTICAST_IF, inet_aton(self.ip))
            sock.sendto(b_code , (self.el_group, self.el_port))
        return 1


    #マルチキャスト受信 受け取ったデータをon_dataに投げる
    def multi_recv(self):
        with closing(socket(AF_INET, SOCK_DGRAM)) as sock:
            sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            sock.bind(('', self.el_port))
            sock.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP,
                            inet_aton(self.el_group)+inet_aton(self.ip))

            while self.flag:
                b_data, addr = sock.recvfrom(self.bufsize)
                data = self.hex2str(b_data)

                if data == '':
                    break

                self.on_data([addr[0], data])

    #受信開始
    def start(self):
        self.flag = True
        self.receiver = Thread(target=self.multi_recv)
        self.receiver.start()
        self.receiver_isalive = True
        sleep(0.001)
        return 1

    #受信停止
    def stop(self):
        self.flag = False
        self.send('127.0.0.1', '')#multi_recv内のループを判定処理まで進ませる
        self.receiver.join()
        self.receiver_isalive = False
        return 1

    #データを受信すると実行される ここをオーバライド
    def on_data(self, data):
        print(data)
        return 1

使い方

from el import ELCliant

class MyCliant(ELCliant):
    def on_data(self, data):
        print('ヽ(*゚д゚)ノ<ジュシン!')
        print(data)

code = "1081000005ff010ef0016201d600"

EL = MyCliant()
EL.start()
EL.multi_send(code)
EL.stop()

出力結果

ヽ(*゚д゚)ノ<ジュシン!
['192.168.10.10', '1081000005ff010ef0016201d600']