diff --git a/main.py b/main.py index 097dfe1..ef1849a 100644 --- a/main.py +++ b/main.py @@ -1,18 +1,23 @@ import sys import logging -logging. +import argparse import zmq +import json +import logging +import hashlib +import socket +import time from src.audio_streaming import AudioStreaming from state import state +from urlparse import urlparse def say(session, message): tts = session.service("ALTextToSpeech") tts.say(message) - def listen_for_messages(session): context = zmq.Context() socket = context.socket(zmq.SUB) @@ -23,6 +28,25 @@ def listen_for_messages(session): poller.register(socket, zmq.POLLIN) logging.info("Listening for messages") + + # Let the CB know we're connected. + pub = context.socket(zmq.PUB) + pub.bind("tcp://*:5555") + + time.sleep(1) + print("Now attempting to send connection data to CB.") + connection_data = { + "event": "robot_connected", + "id": state.__getattribute__("id"), + "name": state.__getattribute__("name"), + "port": state.__getattribute__("port") + } + + connection_json = json.dumps(connection_data) + pub.send_string(connection_json) + print("Send data: ", connection_json) + + while not state.exit_event.is_set(): if not poller.poll(200): continue # At most 200 ms delay after CTRL+C # We now know there's a message waiting for us @@ -31,34 +55,71 @@ def listen_for_messages(session): if session: say(session, message) - def get_session(): if "--qi-url" not in sys.argv: logging.info("No Qi URL argument given. Running in stand-alone mode.") - return None + ip = resolve_local_ip() + port = -1 + return None, ip, port + + parser = argparse.ArgumentParser() + parser.add_argument("--qi-url", type=str, help="Qi URL argument") + parser.add_argument("--name", type=str, default="Robot without name", help="Optional robot name") + args = parser.parse_args() + + name = args.name + parsed = urlparse(args.qi_url) + ip = parsed.hostname + port = parsed.port + + # If URL uses localhost, get own ip instead + if ip in ("localhost", "127.0.0.1"): + ip = resolve_local_ip() try: import qi except ImportError: logging.info("Unable to import qi. Running in stand-alone mode.") - return None + return None, ip, port, name try: app = qi.Application() app.start() - return app.session + return app.session, ip, port, name except RuntimeError: logging.info("Unable to connect to the robot. Running in stand-alone mode.") - return None + return None, ip, port, name +def resolve_local_ip(): + """Return the actual local IP, not 127.0.0.1.""" + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("8.8.8.8", 80)) # Use a public IP just to resolve interface + ip = s.getsockname()[0] + s.close() + return ip + except Exception as e: + logging.warning("Could not resolve local IP: {}".format(e)) + return "127.0.0.1" + def main(): - session = get_session() + session, ip, port, name = get_session() - audio_streamer = AudioStreaming() - audio_streamer.run() + # hash ip, port into id + id_source = "{}:{}".format(ip, port) + unique_id = hashlib.md5(id_source).hexdigest() - listen_for_messages(session) # Runs indefinitely, until CTRL+C + print("created unique id: ", unique_id) + + state.id = unique_id + state.port = port + state.ip = ip + state.name = name + + logging.info("Session ID: {} (from {})".format(unique_id, id_source)) + + listen_for_messages(session) if __name__ == "__main__": diff --git a/src/__init__.pyc b/src/__init__.pyc new file mode 100644 index 0000000..ef345bc Binary files /dev/null and b/src/__init__.pyc differ diff --git a/src/audio_streaming.pyc b/src/audio_streaming.pyc new file mode 100644 index 0000000..7908613 Binary files /dev/null and b/src/audio_streaming.pyc differ diff --git a/state.py b/state.py index 5d6b166..cf33ca0 100644 --- a/state.py +++ b/state.py @@ -35,7 +35,7 @@ class State(object): def __getattribute__(self, name): # Enforce that the state is initialized before accessing any property (aside from the basic ones) - if name in ("initialize", "deinitialize", "is_initialized", "__dict__", "__class__"): + if name in ("initialize", "deinitialize", "is_initialized", "__dict__", "__class__", "id", "name", "ip", "port"): return object.__getattribute__(self, name) if not object.__getattribute__(self, "is_initialized"): diff --git a/state.pyc b/state.pyc new file mode 100644 index 0000000..78f993d Binary files /dev/null and b/state.pyc differ