From 6a4a4239b2c5be9c8b659bd180b97176bfaae978 Mon Sep 17 00:00:00 2001 From: Spoon <2459581+MrSpoon@users.noreply.github.com> Date: Sat, 17 Apr 2021 19:39:05 -0500 Subject: [PATCH 1/4] Replace scripts with service file --- README.md | 55 ++++++-------------------------------------- scripts/kill_command | 1 - scripts/remo.service | 14 +++++++++++ scripts/repeat_start | 6 ----- scripts/start_robot | 6 ----- 5 files changed, 21 insertions(+), 61 deletions(-) delete mode 100755 scripts/kill_command create mode 100644 scripts/remo.service delete mode 100755 scripts/repeat_start delete mode 100755 scripts/start_robot diff --git a/README.md b/README.md index df47cc3..bed8b6b 100644 --- a/README.md +++ b/README.md @@ -99,65 +99,24 @@ The RasPi will need the following things install so it can talk to your motors a - `cozmo_tts` - `google_cloud` -## Setting up your start_robot file on the Raspberry Pi +## Setting up the remotv service on the Raspberry Pi -1. Copy the `start_robot` script to your home directory. +1. Link the service file to systemctl ```sh - cp ~/remotv/scripts/start_robot ~ + sudo systemctl link /home/pi/remotv/script/remotv.service ``` -2. Add the startup script to the `crontab` +2. Enable the service to run at startup ```sh - crontab -e + sudo systemctl enable remotv.service ``` - Note: If you accidently use the wrong editor try +3. Start the service ```sh - EDITOR=nano crontab -e - ``` - -3. Insert the following text at the bottom - - ```sh - @reboot /bin/bash /home/pi/start_robot - ``` - - Example: - - ```sh - # Edit this file to introduce tasks to be run by cron. - # - # Each task to run has to be defined through a single line - # indicating with different fields when the task will be run - # and what command to run for the task - # - # To define the time you can provide concrete values for - # minute (m), hour (h), day of month (dom), month (mon), - # and day of week (dow) or use '*' in these fields (for 'any').# - # Notice that tasks will be started based on the cron's system - # daemon's notion of time and timezones. - # - # Output of the crontab jobs (including errors) is sent through - # email to the user the crontab file belongs to (unless redirected). - # - # For example, you can run a backup of all your user accounts - # at 5 a.m every week with: - # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ - # - # For more information see the manual pages of crontab(5) and cron(8) - # - # m h dom mon dow command - - @reboot /bin/bash /home/pi/start_robot - ``` - -4. Now just plug in the Camera and USB Speaker and reboot - - ```sh - sudo reboot + sudo systemctl start remotv.service ``` # Hardware Compatibility diff --git a/scripts/kill_command b/scripts/kill_command deleted file mode 100755 index 7bce5ba..0000000 --- a/scripts/kill_command +++ /dev/null @@ -1 +0,0 @@ -sudo killall /bin/bash python ffmpeg diff --git a/scripts/remo.service b/scripts/remo.service new file mode 100644 index 0000000..5e7a5b8 --- /dev/null +++ b/scripts/remo.service @@ -0,0 +1,14 @@ +[Unit] +After=network.target +Description=Remo.Tv startup script +Documentation=https://docs.remo.tv + +[Install] +WantedBy=multi-user.target + +[Service] +ExecStart=/usr/bin/python2 /home/pi/remotv/controller.py +Restart=on-failure +RestartSec=10 +Type=simple +WorkingDirectory=/home/pi/remotv diff --git a/scripts/repeat_start b/scripts/repeat_start deleted file mode 100755 index 93c93a0..0000000 --- a/scripts/repeat_start +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -while : - do - $@ - sleep 1.0 -done diff --git a/scripts/start_robot b/scripts/start_robot deleted file mode 100755 index 3006cf6..0000000 --- a/scripts/start_robot +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# suggested use for this: -# (1) use "crontab -e" to create a crontab entry: @reboot /bin/bash /home/pi/start_robot - -cd /home/pi/remotv -nohup scripts/repeat_start python controller.py &> /dev/null & From 38c30a28bd43ef1c3d7c4edc2c98c99c41f6557c Mon Sep 17 00:00:00 2001 From: Spoon <2459581+MrSpoon@users.noreply.github.com> Date: Mon, 19 Apr 2021 18:47:18 -0500 Subject: [PATCH 2/4] Move boot message Delays TTS boot message until robot is full connected and ready for commands. --- controller.py | 30 +++++++++++++++++++++++++++--- networking.py | 38 ++++++-------------------------------- scripts/remo.service | 5 ++++- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/controller.py b/controller.py index aa66381..f534644 100755 --- a/controller.py +++ b/controller.py @@ -2,7 +2,8 @@ # TODO move all defs to the top of the file, out of the way of the flow of execution. # TODO full python3 support will involve installing the adafruit drivers, not using the ones from the repo - +import random +import re import traceback import argparse import robot_util @@ -132,7 +133,7 @@ def write(self, config_file): log.setLevel(logging.DEBUG) console_handler=logging.StreamHandler() console_handler.setLevel(logging.getLevelName(robot_config.get('logging', 'console_level'))) -console_formatter=logging.Formatter('%(asctime)s - %(filename)s : %(message)s','%H:%M:%S') +console_formatter=logging.Formatter('%(asctime)s - %(filename)s[%(lineno)d]: %(message)s','%H:%M:%S') console_handler.setFormatter(console_formatter) try: file_handler=logging.handlers.RotatingFileHandler(robot_config.get('logging', 'log_file'), @@ -244,7 +245,30 @@ def handle_message(ws, message): elif event == "ROBOT_VALIDATED": networking.handleConnectChatChannel(data["host"]) - + elif event == "SEND_CHAT": + # At this point the bot is fully online and ready for commands. Therefore it's boot message time. + log.info("Robot online and ready for action") + bootMessages = robot_config.get('tts', 'boot_message') + bootMessageList = bootMessages.split(',') + bootMessage = random.choice(bootMessageList) + ipAddr = False + ood = False + 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() + log.info('IPv4 Addr : {}'.format(addr)) + bootMessage = bootMessage + ". My IP address is {}".format(addr) + + if robot_config.has_option('tts', 'announce_out_of_date'): + ood = robot_config.getboolean('tts', 'announce_out_of_date') + if ood: + isOod = os.popen('git fetch && git status').read().rstrip() + 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)) + tts.say(bootMessage) else: log.error("Unknown event type") diff --git a/networking.py b/networking.py index 0959298..e2e3660 100644 --- a/networking.py +++ b/networking.py @@ -1,16 +1,13 @@ -import sys -import robot_util import json -import schedule -import tts.tts as tts -import watchdog import logging -import random +import sys + import websocket -import os -import re + import robot_util import schedule +import tts.tts as tts +import watchdog if (sys.version_info > (3, 0)): # import _thread as thread @@ -106,7 +103,6 @@ def checkWebSocket(): def setupWebSocket(robot_config, onHandleMessage): global robot_key - global bootMessage global webSocket global server global version @@ -126,26 +122,6 @@ def setupWebSocket(robot_config, onHandleMessage): if robot_config.has_option('robot', 'channel'): channel = robot_config.get('robot', 'channel') - bootMessages = robot_config.get('tts', 'boot_message') - bootMessageList = bootMessages.split(',') - bootMessage = random.choice(bootMessageList) - - 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() - log.info('IPv4 Addr : {}'.format(addr)) - bootMessage = bootMessage + ". My IP address is {}".format(addr) - - if robot_config.has_option('tts', 'announce_out_of_date'): - ood = robot_config.getboolean('tts', 'announce_out_of_date') - if ood: - isOod = os.popen('git fetch && git status').read().rstrip() - 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)) - # 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, @@ -156,7 +132,7 @@ def setupWebSocket(robot_config, onHandleMessage): log.info("staring websocket listen process") startListenForWebSocket() - schedule.single_task(5, checkWebSocket) + schedule.single_task(10, checkWebSocket) if robot_config.getboolean('misc', 'check_internet'): #schedule a task to check internet status @@ -186,14 +162,12 @@ def isInternetConnected(): lastInternetStatus = False def internetStatus_task(): - global bootMessage global lastInternetStatus global internetStatus internetStatus = isInternetConnected() if internetStatus != lastInternetStatus: if internetStatus: - tts.say(bootMessage) log.info("internet connected") else: log.info("missing internet connection") diff --git a/scripts/remo.service b/scripts/remo.service index 5e7a5b8..9be3bac 100644 --- a/scripts/remo.service +++ b/scripts/remo.service @@ -9,6 +9,9 @@ WantedBy=multi-user.target [Service] ExecStart=/usr/bin/python2 /home/pi/remotv/controller.py Restart=on-failure -RestartSec=10 +RestartSec=1 +StartLimitBurst=5 +StartLimitInterval=60 +SyslogIdentifier=remo-controller Type=simple WorkingDirectory=/home/pi/remotv From 475acada2e44cef33e2862d55c0333741955e83a Mon Sep 17 00:00:00 2001 From: Spoon <2459581+MrSpoon@users.noreply.github.com> Date: Mon, 19 Apr 2021 22:31:48 -0500 Subject: [PATCH 3/4] Restore deleted files Restore deleted files to maintain backwards compatibility. --- scripts/kill_command | 1 + scripts/repeat_start | 6 ++++++ scripts/start_robot | 6 ++++++ 3 files changed, 13 insertions(+) create mode 100755 scripts/kill_command create mode 100755 scripts/repeat_start create mode 100755 scripts/start_robot diff --git a/scripts/kill_command b/scripts/kill_command new file mode 100755 index 0000000..7bce5ba --- /dev/null +++ b/scripts/kill_command @@ -0,0 +1 @@ +sudo killall /bin/bash python ffmpeg diff --git a/scripts/repeat_start b/scripts/repeat_start new file mode 100755 index 0000000..93c93a0 --- /dev/null +++ b/scripts/repeat_start @@ -0,0 +1,6 @@ +#!/bin/bash +while : + do + $@ + sleep 1.0 +done diff --git a/scripts/start_robot b/scripts/start_robot new file mode 100755 index 0000000..3006cf6 --- /dev/null +++ b/scripts/start_robot @@ -0,0 +1,6 @@ +#!/bin/bash +# suggested use for this: +# (1) use "crontab -e" to create a crontab entry: @reboot /bin/bash /home/pi/start_robot + +cd /home/pi/remotv +nohup scripts/repeat_start python controller.py &> /dev/null & From e7e852fd9e06ad91eec6518465fab3e2783f352a Mon Sep 17 00:00:00 2001 From: Spoon <2459581+MrSpoon@users.noreply.github.com> Date: Tue, 20 Apr 2021 09:33:35 -0500 Subject: [PATCH 4/4] Restore TTS Misread the problem on issue #20. It was not an issue with the tts but with a continuous restarting loop due to api authentication failure. --- controller.py | 29 ++++------------------------- controller.sample.conf | 2 +- networking.py | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/controller.py b/controller.py index f534644..00ef34f 100755 --- a/controller.py +++ b/controller.py @@ -2,8 +2,7 @@ # TODO move all defs to the top of the file, out of the way of the flow of execution. # TODO full python3 support will involve installing the adafruit drivers, not using the ones from the repo -import random -import re + import traceback import argparse import robot_util @@ -245,30 +244,10 @@ def handle_message(ws, message): elif event == "ROBOT_VALIDATED": networking.handleConnectChatChannel(data["host"]) + elif event == "SEND_CHAT": - # At this point the bot is fully online and ready for commands. Therefore it's boot message time. - log.info("Robot online and ready for action") - bootMessages = robot_config.get('tts', 'boot_message') - bootMessageList = bootMessages.split(',') - bootMessage = random.choice(bootMessageList) - ipAddr = False - ood = False - 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() - log.info('IPv4 Addr : {}'.format(addr)) - bootMessage = bootMessage + ". My IP address is {}".format(addr) - - if robot_config.has_option('tts', 'announce_out_of_date'): - ood = robot_config.getboolean('tts', 'announce_out_of_date') - if ood: - isOod = os.popen('git fetch && git status').read().rstrip() - 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)) - tts.say(bootMessage) + pass + else: log.error("Unknown event type") diff --git a/controller.sample.conf b/controller.sample.conf index 41aaeec..53b9c00 100644 --- a/controller.sample.conf +++ b/controller.sample.conf @@ -149,7 +149,7 @@ boot_message=ok announce_ip=False # Announces when the cloned repo is out of date and by how many commits. -annouce_out_of_date=False +announce_out_of_date=False # Enable delayed TTS, this allows a window for moderators to remove messages # before they get passed to TTS. Messenger must be enabled for this to function. diff --git a/networking.py b/networking.py index e2e3660..4a77c29 100644 --- a/networking.py +++ b/networking.py @@ -1,13 +1,16 @@ -import json -import logging import sys - -import websocket - import robot_util +import json import schedule import tts.tts as tts import watchdog +import logging +import random +import websocket +import os +import re +import robot_util +import schedule if (sys.version_info > (3, 0)): # import _thread as thread @@ -103,6 +106,7 @@ def checkWebSocket(): def setupWebSocket(robot_config, onHandleMessage): global robot_key + global bootMessage global webSocket global server global version @@ -122,6 +126,26 @@ def setupWebSocket(robot_config, onHandleMessage): if robot_config.has_option('robot', 'channel'): channel = robot_config.get('robot', 'channel') + bootMessages = robot_config.get('tts', 'boot_message') + bootMessageList = bootMessages.split(',') + bootMessage = random.choice(bootMessageList) + + 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() + log.info('IPv4 Addr : {}'.format(addr)) + bootMessage = bootMessage + ". My IP address is {}".format(addr) + + if robot_config.has_option('tts', 'announce_out_of_date'): + ood = robot_config.getboolean('tts', 'announce_out_of_date') + if ood: + isOod = os.popen('git fetch && git status').read().rstrip() + 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)) + # 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, @@ -162,12 +186,14 @@ def isInternetConnected(): lastInternetStatus = False def internetStatus_task(): + global bootMessage global lastInternetStatus global internetStatus internetStatus = isInternetConnected() if internetStatus != lastInternetStatus: if internetStatus: + tts.say(bootMessage) log.info("internet connected") else: log.info("missing internet connection")