引き続き、PythonでIP Messengerのサービスにエントリして送られてくるメッセージを処理する辺りを。前回今回Raspberry Pi関係ないですね。
import socket
import random
USER_NAME = 'ipmsg_light'
MACHINE_NAME = 'raspberrypi'
BROADCAST = '255.255.255.255'
IPMSG_VERSION = 1
IPMSG_DEFAULT_PORT = 2425
IPMSG_BR_ENTRY = 0x00000001L
IPMSG_BR_EXIT = 0x00000002L
IPMSG_ANSENTRY = 0x00000003L
IPMSG_BR_ABSENCE = 0x00000004L
IPMSG_SENDMSG = 0x00000020L
IPMSG_RECVMSG = 0x00000021L
PORT = IPMSG_DEFAULT_PORT
# -----
def turn_the_light_on():
print 'light on.'
def turn_the_light_off():
print 'light off.'
def get_mode(command):
return command & 0x000000FFL
def get_msg_header(cmd, msg):
packet_num = random.randrange(1, 10000000)
return "%s:%s:%s:%s:%s:%s" % (IPMSG_VERSION, packet_num, USER_NAME, MACHINE_NAME, cmd, msg)
def get_ans_cmd(cmd):
if cmd == IPMSG_BR_ENTRY:
return IPMSG_ANSENTRY
elif cmd == IPMSG_SENDMSG:
return IPMSG_RECVMSG
return -1
def set_light_status_by_user_status(user_dic):
if len(user_dic) == 0:
turn_the_light_off()
elif reduce(lambda x,y: x+y, user_dic.values()) == 0:
turn_the_light_off()
else:
turn_the_light_on()
def set_light_status(user, msg_text, user_dic):
if user not in user_dic:
user_dic[user] = 0
msg_cmd = msg_text.replace("\0", '').strip().lower()
if msg_cmd == "on":
user_dic[user] = 1
elif msg_cmd == 'off':
user_dic[user] = 0
elif msg_cmd == 'kill':
user_dic.clear()
else:
user_dic[user] = (0 if user_dic[user] == 1 else 1)
set_light_status_by_user_status(user_dic)
def remove_user(user, user_dic):
if user in user_dic:
user_dic.pop(user)
set_light_status_by_user_status(user_dic)
def parse_recv_msg(msg):
msg_ary = msg.split(':')
if len(msg_ary) < 5 :
return
return (msg_ary[1], msg_ary[2], msg_ary[3], msg_ary[4], msg_ary[5])
# -----
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind(('0.0.0.0', PORT))
msg = get_msg_header(IPMSG_BR_ENTRY, '')
s.sendto(msg, (BROADCAST, PORT))
user_dic = {}
while True:
(recv_msg, client_addr) = s.recvfrom(1024)
print recv_msg
msg_tuple = parse_recv_msg(recv_msg)
if msg_tuple is None:
continue
(packet_num, send_user, send_machine, recv_cmd, recv_msg_text) = msg_tuple
cmd = get_mode(int(recv_cmd))
if cmd == IPMSG_SENDMSG:
set_light_status(send_user, recv_msg_text, user_dic)
elif cmd == IPMSG_BR_EXIT:
remove_user(send_user, user_dic)
ans_cmd = get_ans_cmd(cmd)
if ans_cmd < 0 :
continue
ans_msg = ''
if ans_cmd == IPMSG_ANSENTRY:
ans_msg = get_msg_header(ans_cmd, USER_NAME)
else :
ans_msg = get_msg_header(ans_cmd, packet_num)
s.sendto(ans_msg, client_addr)
s.close()
こんな感じで他のIP Messengerから送られてくるメッセージを処理できてる気がします。正直Python詳しくないので適当です。
基本的にメッセージ本文無しで回転灯をON/OFFさせるように考えていますが、本文にonかoffが書かれていればそれに従い、killとあれば他のユーザの状況にかかわらず常にOFFにするようにしてみました。
とりあえずメッセージを受けて回転灯の状態を操作できそうになったので、on/off文字をprintしている箇所を変更してRaspberry PiのGPIOを弄っていきます。