diff --git a/controller.py b/controller.py index aa66381..47e5d45 100755 --- a/controller.py +++ b/controller.py @@ -46,8 +46,8 @@ def unregister(func, *targs, **kargs): sys.exit() try: - with open('controller.conf', 'r') as fp: - robot_config.readfp(fp) + # Values in controller.conf will overwrite values in controller.sample.conf + robot_config.read(['controller.sample.conf', 'controller.conf']) except IOError: print("unable to read controller.conf, please check that you have copied controller.sample.conf to controller.conf and modified it appropriately.") sys.exit() diff --git a/controller.sample.conf b/controller.sample.conf index 4de7dd3..2efed54 100644 --- a/controller.sample.conf +++ b/controller.sample.conf @@ -344,6 +344,8 @@ num_backup=2 [misc] # host server to connect to server = remo.tv +# API server to connect to. This is needed for testing on local instances. +api_server = remo.tv # API version is the version of the API. api_version = dev # video server to connect to so you can use local websocket and remote video server @@ -362,6 +364,8 @@ watchdog = True # Enable async handling of commands, your handler will either need to be able to # function asyncronously or it will need it's own blocking. enable_async=False +# Local instances will not use secure HTTP or WebSockets +secure_server=True # Periodically check internet connection status, and report failure / connect # over tts diff --git a/networking.py b/networking.py index 0959298..6d4eac4 100644 --- a/networking.py +++ b/networking.py @@ -13,17 +13,19 @@ import schedule if (sys.version_info > (3, 0)): -# import _thread as thread + # import _thread as thread import urllib.request as urllib2 else: -# import thread - import urllib2 #pylint: disable=import-error + # import thread + import urllib2 # pylint: disable=import-error log = logging.getLogger('RemoTV.networking') robot_key = None webSocket = None server = None +api_server = None +secure_server = None version = None channel = None channel_id = None @@ -40,12 +42,17 @@ ood = None + def getChatChannels(host): - url = 'https://%s/api/%s/channels/list/%s' % (server, version, host) + if (secure_server): + url = 'https://%s/api/%s/channels/list/%s' % (api_server, version, host) + else: + url = 'http://%s/api/%s/channels/list/%s' % (api_server, version, host) response = robot_util.getWithRetry(url) log.debug("getChatChannels : %s", response) return json.loads(response) + def waitForWebSocket(): while True: try: @@ -53,24 +60,30 @@ def waitForWebSocket(): except AttributeError: log.warning("Warning: Web Socket not connected.") + def startListenForWebSocket(): global webSocket watchdog.start("WebSocketListen", waitForWebSocket) + def onHandleWebSocketOpen(ws): ws.send(json.dumps({"e": "AUTHENTICATE_ROBOT", "d": {"token": robot_key}})) - log.debug(json.dumps({"e": "AUTHENTICATE_ROBOT", "d": {"token": robot_key}})) + log.debug(json.dumps( + {"e": "AUTHENTICATE_ROBOT", "d": {"token": robot_key}})) log.info("websocket connected") + def onHandleWebSocketClose(ws): global authenticated authenticated = False log.info("websocket disconnect") + def onHandleWebSocketError(ws, error): log.error("WebSocket ERROR: {}".format(error)) + def handleConnectChatChannel(host): global channel_id global chat @@ -84,13 +97,15 @@ def handleConnectChatChannel(host): if key["name"] == channel: channel_id = key["id"] chat = key["chat"] - log.info("channel {} found with id : {}".format(channel, channel_id)) + log.info("channel {} found with id : {}".format( + channel, channel_id)) break if channel_id == None: channel_id = response["channels"][0]["id"] chat = response["channels"][0]["chat"] - log.warning("channel {} NOT found, joining : {}".format(channel, channel_id)) + log.warning("channel {} NOT found, joining : {}".format( + channel, channel_id)) webSocket.send(json.dumps( {"e": "JOIN_CHANNEL", "d": channel_id})) @@ -98,17 +113,21 @@ def handleConnectChatChannel(host): {"e": "GET_CHAT", "d": chat})) authenticated = True + def checkWebSocket(): if not authenticated: log.critical("Websocket failed to connect or authenticate correctly") robot_util.terminate_controller() + def setupWebSocket(robot_config, onHandleMessage): global robot_key global bootMessage global webSocket global server + global api_server + global secure_server global version global ipAddr global ood @@ -117,6 +136,8 @@ def setupWebSocket(robot_config, onHandleMessage): robot_key = robot_config.get('robot', 'robot_key') server = robot_config.get('misc', 'server') + api_server = robot_config.get('misc', 'api_server') + secure_server = robot_config.getboolean('misc', 'secure_server') if robot_config.has_option('misc', 'api_version'): version = robot_config.get('misc', 'api_version') @@ -133,7 +154,8 @@ def setupWebSocket(robot_config, onHandleMessage): if robot_config.has_option('tts', 'announce_ip'): ipAddr = robot_config.getboolean('tts', 'announce_ip') if ipAddr: - addr = os.popen("ip -4 addr show wlan0 | grep -oP \'(?<=inet\\s)\\d+(\\.\\d+){3}\'").read().rstrip() + addr = os.popen( + "ip -4 addr show wlan0 | grep -oP \'(?<=inet\\s)\\d+(\\.\\d+){3}\'").read().rstrip() log.info('IPv4 Addr : {}'.format(addr)) bootMessage = bootMessage + ". My IP address is {}".format(addr) @@ -144,38 +166,52 @@ def setupWebSocket(robot_config, onHandleMessage): if "behind" in isOod: commits = re.search(r'\d+(\scommits|\scommit)', isOod) log.warning('Git repo is out of date. Run "git pull" to update.') - bootMessage = bootMessage + ". Git repo is behind by {}.".format(commits.group(0)) + bootMessage = bootMessage + \ + ". Git repo is behind by {}.".format(commits.group(0)) # log.info("using socket io to connect to control %s", controlHostPort) - log.info("configuring web socket wss://%s/" % server) - webSocket = websocket.WebSocketApp("wss://%s/" % server, - on_message=onHandleMessage, - on_error=onHandleWebSocketError, - on_open=onHandleWebSocketOpen, - on_close=onHandleWebSocketClose) + log.info("configuring web socket wss://%s/" % api_server) + if (secure_server): + webSocket = websocket.WebSocketApp("wss://%s/" % api_server, + on_message=onHandleMessage, + on_error=onHandleWebSocketError, + on_open=onHandleWebSocketOpen, + on_close=onHandleWebSocketClose) + else: + webSocket = websocket.WebSocketApp("ws://%s/" % api_server, + on_message=onHandleMessage, + on_error=onHandleWebSocketError, + on_open=onHandleWebSocketOpen, + on_close=onHandleWebSocketClose) log.info("staring websocket listen process") startListenForWebSocket() schedule.single_task(5, checkWebSocket) - + if robot_config.getboolean('misc', 'check_internet'): - #schedule a task to check internet status - schedule.task(robot_config.getint('misc', 'check_freq'), internetStatus_task) + # schedule a task to check internet status + schedule.task(robot_config.getint( + 'misc', 'check_freq'), internetStatus_task) + def sendChatMessage(message): log.info("Sending Message : %s" % message) webSocket.send(json.dumps( - {"e": "ROBOT_MESSAGE_SENT", + {"e": "ROBOT_MESSAGE_SENT", "d": {"message": "%s" % message, "chatId": "%s" % chat, "server_id": "%s" % server, "channel_id": "%s" % channel_id - } - })) + } + })) + def isInternetConnected(): try: - url = 'https://{}'.format(server) + if (secure_server): + url = 'https://{}'.format(server) + else: + url = 'http://{}'.format(server) urllib2.urlopen(url, timeout=1) log.debug("Server Detected") return True @@ -183,8 +219,10 @@ def isInternetConnected(): log.debug("Server NOT Detected {}".format(url)) return False + lastInternetStatus = False + def internetStatus_task(): global bootMessage global lastInternetStatus