From 515489313591579535f133b09e5c59c2e7e321f5 Mon Sep 17 00:00:00 2001 From: Raymond Oung Date: Thu, 23 Jul 2020 23:15:52 +0900 Subject: [PATCH 1/3] Synchronizes with JS version --- temipy/robot.py | 64 +++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/temipy/robot.py b/temipy/robot.py index 8b66c66..25292e9 100644 --- a/temipy/robot.py +++ b/temipy/robot.py @@ -18,73 +18,85 @@ def __init__(self, mqtt_client, temi_serial): """ self.client = mqtt_client - self.serial = temi_serial + self.id = temi_serial def rotate(self, angle): - """Rotate robot + """Rotate """ print("[CMD] Rotate: {} [deg]".format(angle)) - topic = "temi/" + self.serial + "/command/move/turn_by" - payload = json.dumps({"angle": angle}) + if (angle != 0): + topic = "temi/" + self.id + "/command/move/turn_by" + payload = json.dumps({"angle": angle}) - self.client.publish(topic, payload, qos=0) + self.client.publish(topic, payload, qos=0) def translate(self, value): - """Translate robot + """Translate """ print("[CMD] Translate: {} [unitless]".format(value)) - if math.copysign(1, value): - topic = "temi/" + self.serial + "/command/move/forward" - elif math.copysign(1, value): - topic = "temi/" + self.serial + "/command/move/backward" + if math.copysign(1, value) > 0: + topic = "temi/" + self.id + "/command/move/forward" + self.client.publish(topic, "{}", qos=0) + elif math.copysign(1, value) < 0: + topic = "temi/" + self.id + "/command/move/backward" + self.client.publish(topic, "{}", qos=0) else: pass # do nothing - self.client.publish(topic, "{}", qos=0) def tilt(self, angle): - """Tilt robot's head (absolute angle) + """Tilt head (absolute angle) """ print("[CMD] Tilt: {} [deg]".format(angle)) - topic = "temi/" + self.serial + "/command/move/tilt" + topic = "temi/" + self.id + "/command/move/tilt" payload = json.dumps({"angle": angle}) self.client.publish(topic, payload, qos=0) def tilt_by(self, angle): - """Tilt robot's head (relative angle) + """Tilt head (relative angle) """ print("[CMD] Tilt By: {} [deg]".format(angle)) - topic = "temi/" + self.serial + "/command/move/tilt_by" + topic = "temi/" + self.id + "/command/move/tilt_by" payload = json.dumps({"angle": angle}) self.client.publish(topic, payload, qos=0) def stop(self): - """Follow + """Stop """ print("[CMD] Stop") - topic = "temi/" + self.serial + "/command/move/stop" + topic = "temi/" + self.id + "/command/move/stop" + + self.client.publish(topic, "{}", qos=1) + + def follow(self): + """Follow + + """ + print("[CMD] Follow") + + topic = "temi/" + self.id + "/command/follow/unconstrained" self.client.publish(topic, "{}", qos=1) def goto(self, location_name): - """Go to a specified location + """Go to a saved location """ print("[CMD] Go-To: {}".format(location_name)) - topic = "temi/" + self.serial + "/command/waypoint/goto" + topic = "temi/" + self.id + "/command/waypoint/goto" payload = json.dumps({"location": location_name}) self.client.publish(topic, payload, qos=1) @@ -95,7 +107,7 @@ def tts(self, text): """ print("[CMD] TTS: {}".format(text)) - topic = "temi/" + self.serial + "/command/tts" + topic = "temi/" + self.id + "/command/tts" payload = json.dumps({"utterance": text}) self.client.publish(topic, payload, qos=1) @@ -106,7 +118,7 @@ def tts(self, text): # """ # print("[CMD] Play Audio: {}".format(url)) - # topic = "temi/" + self.serial + "/command/media/audio" + # topic = "temi/" + self.id + "/command/media/audio" # payload = json.dumps({"url": url}) # self.client.publish(topic, payload, qos=1) @@ -117,7 +129,7 @@ def video(self, url): """ print("[CMD] Play Video: {}".format(url)) - topic = "temi/" + self.serial + "/command/media/video" + topic = "temi/" + self.id + "/command/media/video" payload = json.dumps({"url": url}) self.client.publish(topic, payload, qos=1) @@ -128,7 +140,7 @@ def youtube(self, video_id): """ print("[CMD] Play YouTube: {}".format(video_id)) - topic = "temi/" + self.serial + "/command/media/youtube" + topic = "temi/" + self.id + "/command/media/youtube" payload = json.dumps({"video_id": video_id}) self.client.publish(topic, payload, qos=1) @@ -139,7 +151,7 @@ def webview(self, url): """ print("[CMD] Show Webview: {}".format(url)) - topic = "temi/" + self.serial + "/command/media/webview" + topic = "temi/" + self.id + "/command/media/webview" payload = json.dumps({"url": url}) self.client.publish(topic, payload, qos=1) @@ -150,7 +162,7 @@ def call(self, room_name): """ print("[CMD] Call: {}".format(room_name)) - topic = "temi/" + self.serial + "/command/call/start" + topic = "temi/" + self.id + "/command/call/start" payload = json.dumps({"room_name": room_name}) self.client.publish(topic, payload, qos=1) @@ -161,6 +173,6 @@ def hangup(self): """ print("[CMD] Hangup") - topic = "temi/" + self.serial + "/command/call/end" + topic = "temi/" + self.id + "/command/call/end" self.client.publish(topic, "{}", qos=1) From d937ff77e88da886eab8dfd39e934d149d8963d6 Mon Sep 17 00:00:00 2001 From: Raymond Oung Date: Sun, 9 Aug 2020 16:20:54 +0900 Subject: [PATCH 2/3] Renames package to pytemi and adds Android intent command --- .gitignore | 4 ++-- README.md | 8 ++++---- {temipy => pytemi}/__init__.py | 0 {temipy => pytemi}/connect.py | 0 {temipy => pytemi}/robot.py | 11 +++++++++++ sample.py | 32 ++++++++++++-------------------- setup.py | 9 ++++++--- 7 files changed, 35 insertions(+), 29 deletions(-) rename {temipy => pytemi}/__init__.py (100%) rename {temipy => pytemi}/connect.py (100%) rename {temipy => pytemi}/robot.py (93%) diff --git a/.gitignore b/.gitignore index 45112f8..91649bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -temipy/__pycache__/ -temipy.egg-info/ +pytemi/__pycache__/ +pytemi.egg-info/ venv/ test.py \ No newline at end of file diff --git a/README.md b/README.md index b995b71..c4c2a07 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# temi Connect Python Package -Control temi using Python scripts over MQTT. +# pytemi +A Python client that can be used with [Connect](https://github.com/hapi-robo/connect/) MQTT bridge for temi. ## Prerequisites @@ -20,7 +20,7 @@ git clone ... Create a Python virtual environment (`venv`) and install all dependencies: ``` -cd temipy/ +cd pytemi/ ./setup.sh ``` @@ -41,7 +41,7 @@ python sample.py ## Sample Script ``` -import temipy as temi +import pytemi as temi TEMI_SERIAL = "01234567890" diff --git a/temipy/__init__.py b/pytemi/__init__.py similarity index 100% rename from temipy/__init__.py rename to pytemi/__init__.py diff --git a/temipy/connect.py b/pytemi/connect.py similarity index 100% rename from temipy/connect.py rename to pytemi/connect.py diff --git a/temipy/robot.py b/pytemi/robot.py similarity index 93% rename from temipy/robot.py rename to pytemi/robot.py index 25292e9..77eb2ef 100644 --- a/temipy/robot.py +++ b/pytemi/robot.py @@ -156,6 +156,17 @@ def webview(self, url): self.client.publish(topic, payload, qos=1) + def app(self, package_name): + """Start Android app + + """ + print("[CMD] Start App: {}".format(package_name)) + + topic = "temi/" + self.id + "/command/app" + payload = json.dumps({"package_name": package_name}) + + self.client.publish(topic, payload, qos=1) + def call(self, room_name): """Start a call diff --git a/sample.py b/sample.py index 97673b5..50ecb43 100644 --- a/sample.py +++ b/sample.py @@ -3,7 +3,7 @@ """Sample script """ -import temipy as temi +import pytemi as temi import time @@ -22,43 +22,35 @@ # -------------------------------------------------------------- # TEXT-TO-SPEECH COMMANDS # -------------------------------------------------------------- -# command the robot to speak robot.tts("Going to the Entrance") # -------------------------------------------------------------- # WAYPOINT COMMANDS # -------------------------------------------------------------- -# command the robot to go to a saved location robot.goto("entrance") # -------------------------------------------------------------- # MOVE COMMANDS # -------------------------------------------------------------- -# tilt the robot's head to +55 degrees (absolute angle) robot.tilt(+45) -time.sleep(3) # wait 3 seconds for action to complete +time.sleep(3) -# tilt the robot's head to -15 degrees (absolute angle) robot.tilt(-15) -time.sleep(3) # wait 3 seconds for action to complete +time.sleep(3) -# tilt the robot's head to +30 degrees (relative angle) robot.tilt_by(+30) -time.sleep(3) # wait 3 seconds for action to complete +time.sleep(3) -# tilt the robot's head to -10 degrees (relative angle) robot.tilt_by(-10) -time.sleep(3) # wait 3 seconds for action to complete +time.sleep(3) -# rotate the robot by 90 degrees (relative angle) robot.rotate(90) -time.sleep(5) # wait 5 seconds for action to complete +time.sleep(5) -# rotate the robot by -30 degrees (relative angle) robot.rotate(-30) -time.sleep(5) # wait 5 seconds for action to complete +time.sleep(5) # -------------------------------------------------------------- @@ -66,18 +58,18 @@ # -------------------------------------------------------------- # play YouTube video by passing in a video ID robot.youtube("ZsEano0qwcg") -time.sleep(30) # wait 30 seconds before performing next action +time.sleep(30) # play online video by passing a URL robot.video( "https://roboteam-assets.s3.eu-central-1.amazonaws.com/ui/skills/tutorials/videos/intorducing+temi.mp4" ) -time.sleep(30) # wait 30 seconds before performing next action +time.sleep(30) # show webview by passing a URL robot.webview("https://www.robotemi.com/") -time.sleep(5) # wait 5 seconds before performing next action +time.sleep(5) robot.webview("https://www.his.co.jp/en/") -time.sleep(5) # wait 5 seconds before performing next action +time.sleep(5) robot.webview("https://hapi-robo.com/") -time.sleep(5) # wait 5 seconds before performing next action +time.sleep(5) diff --git a/setup.py b/setup.py index d148389..82342fc 100644 --- a/setup.py +++ b/setup.py @@ -5,18 +5,21 @@ def readme(): with open("README.md", "r") as f: return f.read() +def requirements(): + with open("requirements.txt", "r") as f: + return f.read().splitlines() setuptools.setup( - name="temipy", + name="pytemi", version="1.0.0", - description="MQTT bridge for temi", + description="A Python client that can be used with Connect MQTT bridge for temi.", long_description=readme(), long_description_content_type="text/markdown", author="R. Oung", author_email="r.oung@hapi-robo.com", url="https://github.com/", packages=setuptools.find_packages(), - install_requires=["paho-mqtt",], + install_requires=requirements(), classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", From 1bcd66d649ce3103d44076c0322d5f5c8686af51 Mon Sep 17 00:00:00 2001 From: ray-hrst <44389573+ray-hrst@users.noreply.github.com> Date: Tue, 18 Aug 2020 08:22:35 +0900 Subject: [PATCH 3/3] Updates README and sample.py comments --- README.md | 27 +++++++++++---------------- sample.py | 46 +++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index c4c2a07..0b45030 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,30 @@ # pytemi -A Python client that can be used with [Connect](https://github.com/hapi-robo/connect/) MQTT bridge for temi. +Control temi using Python scripts over MQTT. ## Prerequisites * [Python 3](https://www.python.org/downloads/) -* Python [virtualenv](https://virtualenv.pypa.io/en/stable/installation.html) -* Connect APK installed on temi, see [here](https://github.com/hapi-robo/connect/tree/devel/android) +* [Connect app](https://github.com/hapi-robo/connect/releases) installed on temi * MQTT broker. Free brokers for testing: * [Eclipse](http://test.mosquitto.org/) * [Mosquitto](http://mqtt.eclipse.org) * [HiveMQ](http://broker.hivemq.com) -## Ubuntu / MacOS Setup -Clone this repository: +## Setup +Clone this repository and install all dependencies with pip: ``` -git clone ... +pip install -r requirements.txt ``` -Create a Python virtual environment (`venv`) and install all dependencies: +For Linux users, there's a script that will create a Python virtual environment (assuming it's installed) and install all dependencies: ``` -cd pytemi/ ./setup.sh ``` -Activate the virtual environment: -``` -source venv/bin/activate -``` - ## Usage -Make sure temi is connected to an MQTT broker via the Connect app. +Make sure the robot is connected to an MQTT broker via the [Connect app](https://github.com/hapi-robo/connect/releases). Edit the `sample.py` script and adjust the `parameters` appropriately, then run: ``` @@ -43,10 +36,12 @@ python sample.py ``` import pytemi as temi +MQTT_HOST = "test.mosquitto.org" +MQTT_PORT = 1883 TEMI_SERIAL = "01234567890" -# connect to the MQTT server -mqtt_client = temi.connect("test.mosquitto.org", 1883) +# connect to the MQTT broker +mqtt_client = temi.connect(MQTT_HOST, MQTT_PORT) # create robot object robot = temi.Robot(mqtt_client, TEMI_SERIAL) diff --git a/sample.py b/sample.py index 50ecb43..671d92b 100644 --- a/sample.py +++ b/sample.py @@ -12,7 +12,7 @@ MQTT_PORT = 1883 TEMI_SERIAL = "01234567890" -# connect to the MQTT server +# connect to the MQTT broker mqtt_client = temi.connect(MQTT_HOST, MQTT_PORT) # create robot object @@ -22,54 +22,54 @@ # -------------------------------------------------------------- # TEXT-TO-SPEECH COMMANDS # -------------------------------------------------------------- -robot.tts("Going to the Entrance") +robot.tts("Going to the Entrance") # command the robot to speak +time.sleep(1) # wait some time for action to complete # -------------------------------------------------------------- # WAYPOINT COMMANDS # -------------------------------------------------------------- -robot.goto("entrance") +robot.goto("entrance") # command the robot to go to a saved location +time.sleep(1) # wait some time for action to complete # -------------------------------------------------------------- # MOVE COMMANDS # -------------------------------------------------------------- -robot.tilt(+45) -time.sleep(3) +robot.tilt(+45) # tilt the robot's head (absolute angle) +time.sleep(3) # wait some time for action to complete -robot.tilt(-15) -time.sleep(3) +robot.tilt(-15) # tilt the robot's head (absolute angle) +time.sleep(3) # wait some time for action to complete -robot.tilt_by(+30) -time.sleep(3) +robot.tilt_by(+30) # tilt the robot's head (relative angle) +time.sleep(3) # wait some time for action to complete -robot.tilt_by(-10) -time.sleep(3) +robot.tilt_by(-10) # tilt the robot's head (relative angle) +time.sleep(3) # wait some time for action to complete -robot.rotate(90) -time.sleep(5) +robot.rotate(90) # rotate the robot (relative angle) +time.sleep(5) # wait some time for action to complete -robot.rotate(-30) -time.sleep(5) +robot.rotate(-30) # rotate the robot (relative angle) +time.sleep(5) # wait some time for action to complete # -------------------------------------------------------------- # MEDIA COMMANDS # -------------------------------------------------------------- -# play YouTube video by passing in a video ID -robot.youtube("ZsEano0qwcg") -time.sleep(30) +robot.youtube("ZsEano0qwcg") # play YouTube video by passing in a YouTube video ID +time.sleep(30) # wait some time for action to complete -# play online video by passing a URL robot.video( "https://roboteam-assets.s3.eu-central-1.amazonaws.com/ui/skills/tutorials/videos/intorducing+temi.mp4" -) -time.sleep(30) +) # play online video by passing a URL +time.sleep(30) # wait some time for action to complete # show webview by passing a URL robot.webview("https://www.robotemi.com/") time.sleep(5) -robot.webview("https://www.his.co.jp/en/") -time.sleep(5) robot.webview("https://hapi-robo.com/") time.sleep(5) +robot.webview("https://www.his.co.jp/en/") +time.sleep(5)