引き続き、PythonでIP Messengerのサービスにエントリして送られてくるメッセージを処理する辺りを。前回今回Raspberry Pi関係ないですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 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を弄っていきます。