Skip to content

Commit dc6d6a4

Browse files
Merge pull request #13 from jupyter-robotics/dev
Improve error handling
2 parents 8dc3206 + ae7c24b commit dc6d6a4

File tree

8 files changed

+153
-83
lines changed

8 files changed

+153
-83
lines changed

content/introduction.ipynb

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"cells": [
33
{
4-
"attachments": {},
54
"cell_type": "markdown",
65
"metadata": {},
76
"source": [
@@ -14,7 +13,7 @@
1413
"metadata": {},
1514
"outputs": [],
1615
"source": [
17-
"%pip install ipynao==0.2"
16+
"%pip install ipynao==0.3"
1817
]
1918
},
2019
{
@@ -45,7 +44,6 @@
4544
]
4645
},
4746
{
48-
"attachments": {},
4947
"cell_type": "markdown",
5048
"metadata": {},
5149
"source": [
@@ -64,7 +62,6 @@
6462
]
6563
},
6664
{
67-
"attachments": {},
6865
"cell_type": "markdown",
6966
"metadata": {},
7067
"source": [
@@ -96,7 +93,9 @@
9693
{
9794
"cell_type": "code",
9895
"execution_count": null,
99-
"metadata": {},
96+
"metadata": {
97+
"tags": []
98+
},
10099
"outputs": [],
101100
"source": [
102101
"tts.say(\"how is it going?\")"
@@ -125,7 +124,6 @@
125124
]
126125
},
127126
{
128-
"attachments": {},
129127
"cell_type": "markdown",
130128
"metadata": {},
131129
"source": [
@@ -244,7 +242,6 @@
244242
]
245243
},
246244
{
247-
"attachments": {},
248245
"cell_type": "markdown",
249246
"metadata": {
250247
"tags": []
@@ -267,7 +264,6 @@
267264
]
268265
},
269266
{
270-
"attachments": {},
271267
"cell_type": "markdown",
272268
"metadata": {},
273269
"source": [
@@ -385,7 +381,6 @@
385381
]
386382
},
387383
{
388-
"attachments": {},
389384
"cell_type": "markdown",
390385
"metadata": {},
391386
"source": [
@@ -425,18 +420,6 @@
425420
"async def little_dance():\n",
426421
" await motion.async_wakeUp()\n",
427422
" await animate.async_run(\"animations/Stand/Gestures/Hey_2\")\n",
428-
" await animate.async_run(\"animations/Stand/Gestures/Enthusiastic_5\")\n",
429-
" await animate.async_run(\"animations/Stand/Gestures/No_9\")\n",
430-
" await motion.async_moveTo(0, 0.2, 0)\n",
431-
" await animate.async_run(\"animations/Stand/Gestures/Explain_9\")\n",
432-
" await animate.async_run(\"animations/Stand/Gestures/You_4\")\n",
433-
" await animate.async_run(\"animations/Stand/Gestures/Explain_11\")\n",
434-
" await motion.async_moveTo(0, -0.2, 0)\n",
435-
" await animate.async_run(\"animations/Stand/Gestures/YouKnowWhat_6\")\n",
436-
" await animate.async_run(\"animations/Stand/Gestures/No_8\")\n",
437-
" await posture.async_goToPosture(\"LyingBack\", 1.0)\n",
438-
" await posture.async_goToPosture(\"Stand\", 1.0)\n",
439-
" await animate.async_run(\"animations/Stand/Gestures/BowShort_1\")\n",
440423
" await motion.async_rest()"
441424
]
442425
},
@@ -451,12 +434,37 @@
451434
"asyncio.ensure_future(little_dance())"
452435
]
453436
},
437+
{
438+
"cell_type": "markdown",
439+
"metadata": {},
440+
"source": [
441+
"### Error Handling"
442+
]
443+
},
454444
{
455445
"cell_type": "code",
456446
"execution_count": null,
457-
"metadata": {},
447+
"metadata": {
448+
"tags": []
449+
},
458450
"outputs": [],
459-
"source": []
451+
"source": [
452+
"w.disconnect()\n",
453+
"w"
454+
]
455+
},
456+
{
457+
"cell_type": "code",
458+
"execution_count": null,
459+
"metadata": {
460+
"tags": []
461+
},
462+
"outputs": [],
463+
"source": [
464+
"out = Output()\n",
465+
"res = asyncio.ensure_future(w.service(\"ALLeds\", out).async_rasta(\"gibberish\"))\n",
466+
"out"
467+
]
460468
}
461469
],
462470
"metadata": {

ipynao/_frontend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
"""
1010

1111
module_name = "ipynao"
12-
module_version = "^0.2.0"
12+
module_version = "^0.3.0"

ipynao/nao_robot.py

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,70 @@
44
# Copyright (c) Isabel Paredes.
55
# Distributed under the terms of the Modified BSD License.
66

7-
"""
7+
'''
88
TODO: Add module docstring
9-
"""
9+
'''
1010

11-
from ipywidgets import DOMWidget
11+
from ipywidgets import DOMWidget, Output
1212
from traitlets import Unicode, Integer
1313
from ._frontend import module_name, module_version
14-
from time import sleep
1514
import asyncio
1615

1716

18-
1917
class NaoRobotService():
2018
name = None
2119
widget = None
2220
output = None
2321

24-
def __init__(self, widget, service_name):
22+
def __init__(self, widget, service_name, output=Output()):
2523
self.name = service_name
2624
self.widget = widget
25+
self.output = output
2726

28-
29-
def create_service_msg(self, method_name, *args, **kwargs):
27+
def _create_msg(self, method_name, *args, **kwargs):
3028
data = {}
31-
data["command"] = "callService"
32-
data["service"] = str(self.name)
33-
data["method"] = str(method_name)
29+
data['command'] = 'callService'
30+
data['service'] = str(self.name)
31+
data['method'] = str(method_name)
3432
# convert tuple to list to avoid empty arg values
35-
data["args"] = list(args)
36-
data["kwargs"] = kwargs
37-
33+
data['args'] = list(args)
34+
data['kwargs'] = kwargs
35+
return data
36+
37+
def call_service(self, method_name, *args, **kwargs):
38+
data = self._create_msg(method_name, *args, **kwargs)
3839
self.widget.send(data)
3940

40-
# TODO: combine msg creating into separate function
41-
async def async_create_service_msg(self, method_name, *args, **kwargs):
42-
data = {}
43-
data["command"] = "callService"
44-
data["service"] = str(self.name)
45-
data["method"] = str(method_name)
46-
# convert tuple to list to avoid empty arg values
47-
data["args"] = list(args)
48-
data["kwargs"] = kwargs
49-
41+
async def async_call_service(self, method_name, *args, **kwargs):
42+
data = self._create_msg(method_name, *args, **kwargs)
5043
self.widget.send(data)
5144

5245
try:
53-
await self.widget.wait_for_change('counter')
46+
self.output.clear_output()
47+
self.output.append_stdout('Calling service... \n')
48+
await self.widget.wait_for_change('counter', self.output)
5449
except Exception as e:
5550
return e
56-
return self.widget.response
51+
return self.widget.response['data']
5752

5853

5954
def __getattr__(self, method_name):
60-
# TODO: add error for when service is not ready
61-
if (method_name[:6] == "async_"):
62-
return lambda *x, **y: self.async_create_service_msg(method_name[6:], *x, **y)
55+
if (method_name[:6] == 'async_'):
56+
return lambda *x, **y: self.async_call_service(method_name[6:], *x, **y)
6357
else:
64-
return lambda *x, **y: self.create_service_msg(method_name, *x, **y)
58+
return lambda *x, **y: self.call_service(method_name, *x, **y)
6559

6660

6761
class NaoRobotWidget(DOMWidget):
68-
"""TODO: Add docstring here
69-
"""
7062
_model_name = Unicode('NaoRobotModel').tag(sync=True)
7163
_model_module = Unicode(module_name).tag(sync=True)
7264
_model_module_version = Unicode(module_version).tag(sync=True)
7365
_view_name = Unicode('NaoRobotView').tag(sync=True)
7466
_view_module = Unicode(module_name).tag(sync=True)
7567
_view_module_version = Unicode(module_version).tag(sync=True)
7668

77-
connected = Unicode("Disconnected").tag(sync=True)
78-
status = Unicode("Not busy").tag(sync=True)
69+
connected = Unicode('Disconnected').tag(sync=True)
70+
status = Unicode('Not busy').tag(sync=True)
7971
counter = Integer(0).tag(sync=True)
8072
response = None
8173

@@ -86,36 +78,47 @@ def __init__(self, **kwargs):
8678

8779

8880
def _handle_frontend_msg(self, model, msg, buffer):
89-
print("Received frontend msg: ", msg)
81+
print('Received frontend msg: ', msg)
9082
self.response = msg
9183

9284

93-
def wait_for_change(widget, value_name):
85+
def wait_for_change(widget, value_name, output=Output()):
9486
future = asyncio.Future()
9587
widget.response = None
9688

9789
def get_value_change(change):
9890
widget.unobserve(get_value_change, names=value_name)
9991
if (widget.response != None):
100-
future.set_result(widget.response)
92+
if (widget.response['isError']):
93+
future.set_exception(Exception(widget.response['data']))
94+
output.append_stderr(widget.response['data'])
95+
else:
96+
future.set_result(widget.response['data'])
97+
output.append_stdout(widget.response['data'])
10198
else:
10299
future.set_result(change)
103100

104101
widget.observe(get_value_change, names=value_name)
105102
return future
106103

107104

108-
def connect(self, ip_address="nao.local", port="80"):
105+
def connect(self, ip_address='nao.local', port='80'):
106+
data = {}
107+
data['command'] = str('connect')
108+
data['ipAddress'] = str(ip_address)
109+
data['port'] = str(port)
110+
self.send(data)
111+
112+
113+
def disconnect(self):
109114
data = {}
110-
data["command"] = str("connect")
111-
data["ipAddress"] = str(ip_address)
112-
data["port"] = str(port)
115+
data['command'] = str('disconnect')
113116
self.send(data)
114117

115118

116-
def service(self, service_name):
119+
def service(self, service_name, output=Output()):
117120
data = {}
118-
data["command"] = str("createService")
119-
data["service"] = str(service_name)
121+
data['command'] = str('createService')
122+
data['service'] = str(service_name)
120123
self.send(data)
121-
return NaoRobotService(self, service_name)
124+
return NaoRobotService(self, service_name, output)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ipynao",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"description": "A widget library for controlling Nao",
55
"keywords": [
66
"jupyter",

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ classifiers = [
3434
dependencies = [
3535
"ipywidgets>=7.0.0",
3636
]
37-
version = "0.2.0"
37+
version = "0.3.0"
3838

3939
[project.optional-dependencies]
4040
docs = [
@@ -104,7 +104,7 @@ file = [
104104
]
105105

106106
[tool.tbump.version]
107-
current = "0.2.0"
107+
current = "0.3.0"
108108
regex = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<channel>a|b|rc|.dev)(?P<release>\\d+))?"
109109

110110
[tool.tbump.git]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ ipympl>=0.8.2
2727
ipycanvas>=0.9.1
2828

2929
# Python: ipynao library for Nao robot
30-
ipynao>=0.2.0
30+
ipynao>=0.3.0
3131

3232
# For examples with images
3333
Pillow

src/qimessaging.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ export class QiSession {
7373
return connected;
7474
}
7575

76+
disconnect() {
77+
this._socket.disconnect();
78+
}
79+
7680
onReply(data: any) {
7781
const idm = data['idm'];
7882
if (

0 commit comments

Comments
 (0)