Skip to content

Commit 67815bf

Browse files
UI and button (#22)
* basic window * run loop with asyncio & command queue * button handling and command queue * update test script, remove print statements * red, green, blue parameters * working textualize ui * readme * build bump * cleanup for class (function consistancy) + bleak upgrade * cleanup for class (function consistancy) + bleak upgrade
1 parent 94fd493 commit 67815bf

File tree

7 files changed

+61
-52
lines changed

7 files changed

+61
-52
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ robot.move(0, 0) # Stop the robot
3636

3737
robot.led(0, 0, 0) # Turn off the LED
3838

39-
a = robot.set_key_binding('a').led(0, 0, 255, 1) # set LED color one button A
40-
w = robot.set_key_binding('w').move(100, 100) # bind move forward to key W
39+
a = robot.setKeyBinding('a').led(0, 0, 255, 1) # set LED color one button A
40+
w = robot.setKeyBinding('w').move(100, 100) # bind move forward to key W
4141
```
4242

4343
## API
@@ -52,8 +52,8 @@ robot = Robot("WAC")
5252

5353
#### Methods
5454

55-
- `led(r: int, g: int, b: int)`: Sets the LED color. Values should be integers between 0 and 255.
56-
- `move(right: int, left: int)`: Sets the motor speeds. Values should be integers between -100 and 100.
55+
- `led(red: int, green: int, blue: int, duration: int)`: Sets the LED color. Values should be integers between 0 and 255.
56+
- `move(left: int, right: int, duration: int)`: Sets the motor speeds. Values should be integers between -100 and 100.
5757
- `wait(duration: float)`: Adds a wait command with a given duration in seconds.
5858
- `run()`: Executes the commands in the order they were added.
5959

demo/test.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
from weallcode_robot import Robot
22

33
# Create a robot
4-
name = "WAC-C9B9"
4+
5+
name = "dink"
56
robot = Robot(name)
67

78
# assign button A to set LED to blue for 1 second
8-
robot.button_a.led(0, 0, 255, 1)
9+
robot.buttonA.led(0, 0, 255, 1)
910

1011
# assign button B to set LED to red & buzz at 440Hz for 0.5 seconds
11-
robot.button_b.led(255, 0, 0)
12+
robot.buttonB.led(255, 0, 0)
1213

13-
a = robot.set_key_binding('a').led(0, 0, 255, 1)
14+
# a = robot.setKeyBinding('a').led(0, 0, 255, 1)
1415

1516
# Display the robot's name (uppercased) on the robot's display for 2.5 seconds
1617
robot.displayText(name.upper(), 2.5)
17-
18+
robot.move(92,100, 1.5)
1819
# Display bullseye for 1 second
1920
robot.displayDots(
20-
# fmt: off
21+
# fmt: offa
2122
[
2223
1, 1, 1, 1, 1,
2324
1, 0, 0, 0, 1,

demo/test_keybindings.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
from weallcode_robot import Robot
22

33
# Create a robot
4+
name = "dink"
45
name = "WAC-2463"
5-
robot = Robot(name)
66

7-
robot.led(0,0,255,1)
7+
# a = robot.setKeyBinding('a').led(0, 0, 255, 1)
8+
# b = robot.setKeyBinding('b').led(255, 0, 0, 1)
9+
# c = robot.setKeyBinding('c').led(0, 255, 0, 1)
810

9-
a = robot.set_key_binding('a').led(0, 0, 255, 1)
10-
b = robot.set_key_binding('b').led(255, 0, 0, 1)
11-
c = robot.set_key_binding('c').led(0, 255, 0, 1)
11+
x = robot.setKeyBinding('x')
12+
x.displayText('x')
1213

13-
w = robot.set_key_binding('w').move(100, 100).displayDots(
14+
15+
w = robot.setKeyBinding('w').move(100, 100).displayDots(
1416
# fmt: off
1517
[
1618
0, 0, 1, 0, 0,
@@ -20,7 +22,9 @@
2022
0, 0, 1, 0, 0,
2123
]
2224
)
23-
a = robot.set_key_binding('a').move(100, 0).displayDots(
25+
26+
a = robot.setKeyBinding('a').move(100, 0).displayDots(
27+
2428
# fmt: off
2529
[
2630
0, 0, 0, 0, 0,
@@ -30,7 +34,9 @@
3034
0, 0, 0, 0, 0,
3135
]
3236
)
33-
s = robot.set_key_binding('d').move(0, 100).displayDots(
37+
38+
s = robot.setKeyBinding('d').move(0, 100).displayDots(
39+
3440
# fmt: off
3541
[
3642
0, 0, 0, 0, 0,
@@ -40,7 +46,9 @@
4046
0, 0, 0, 0, 0,
4147
]
4248
)
43-
d = robot.set_key_binding('s').move(-100, -100).displayDots(
49+
50+
d = robot.setKeyBinding('s').move(-100, -100).displayDots(
51+
4452
# fmt: off
4553
[
4654
0, 0, 1, 0, 0,

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "weallcode_robot"
7-
version = "3.0.3"
7+
version = "3.1.0"
88
description = "Micro:bit TinyBit BLE Python Library"
99
license = "MIT"
1010
authors = [
@@ -38,7 +38,7 @@ profile = "black"
3838

3939
[tool.poetry.dependencies]
4040
python = "^3.11"
41-
bleak = "^0.20.1"
41+
bleak = "^0.22.1"
4242

4343
[tool.poetry.group.dev.dependencies]
4444
black = "^23.3.0"

weallcode_robot/commands.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def led(self, red, green, blue, duration: float = 0):
2929
self.wait(duration)
3030
return self
3131

32-
def move(self, right, left, duration: float = 0):
32+
def move(self, left, right, duration: float = 0):
3333
self.put(MoveCommand(left, right))
3434
self.wait(duration)
3535
return self

weallcode_robot/robot.py

+21-21
Original file line numberDiff line numberDiff line change
@@ -57,31 +57,31 @@ def __init__(self, name, debug=False):
5757
self.buzz = self.main_queue.buzz
5858
self.clear = self.main_queue.clear
5959

60-
self.button_a = DynamicObject()
61-
self.button_a.led = self.button_a_queue.led
62-
self.button_a.move = self.button_a_queue.move
63-
self.button_a.stop = self.button_a_queue.stop
64-
self.button_a.wait = self.button_a_queue.wait
65-
self.button_a.displayText = self.button_a_queue.displayText
66-
self.button_a.displayDots = self.button_a_queue.displayDots
67-
self.button_a.clearDisplay = self.button_a_queue.clearDisplay
68-
self.button_a.buzz = self.button_a_queue.buzz
69-
self.button_a.clear = self.button_a_queue.clear
60+
self.buttonA = DynamicObject()
61+
self.buttonA.led = self.button_a_queue.led
62+
self.buttonA.move = self.button_a_queue.move
63+
self.buttonA.stop = self.button_a_queue.stop
64+
self.buttonA.wait = self.button_a_queue.wait
65+
self.buttonA.displayText = self.button_a_queue.displayText
66+
self.buttonA.displayDots = self.button_a_queue.displayDots
67+
self.buttonA.clearDisplay = self.button_a_queue.clearDisplay
68+
self.buttonA.buzz = self.button_a_queue.buzz
69+
self.buttonA.clear = self.button_a_queue.clear
7070

71-
self.button_b = DynamicObject()
72-
self.button_b.led = self.button_b_queue.led
73-
self.button_b.move = self.button_b_queue.move
74-
self.button_b.stop = self.button_b_queue.stop
75-
self.button_b.wait = self.button_b_queue.wait
76-
self.button_b.displayText = self.button_b_queue.displayText
77-
self.button_b.displayDots = self.button_b_queue.displayDots
78-
self.button_b.clearDisplay = self.button_b_queue.clearDisplay
79-
self.button_b.buzz = self.button_b_queue.buzz
80-
self.button_b.clear = self.button_b_queue.clear
71+
self.buttonB = DynamicObject()
72+
self.buttonB.led = self.button_b_queue.led
73+
self.buttonB.move = self.button_b_queue.move
74+
self.buttonB.stop = self.button_b_queue.stop
75+
self.buttonB.wait = self.button_b_queue.wait
76+
self.buttonB.displayText = self.button_b_queue.displayText
77+
self.buttonB.displayDots = self.button_b_queue.displayDots
78+
self.buttonB.clearDisplay = self.button_b_queue.clearDisplay
79+
self.buttonB.buzz = self.button_b_queue.buzz
80+
self.buttonB.clear = self.button_b_queue.clear
8181

8282
atexit.register(self.ui.run)
8383

84-
def set_key_binding(self, key) -> CommandQueue:
84+
def setKeyBinding(self, key) -> CommandQueue:
8585
valid_keys = {
8686
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
8787
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',

weallcode_robot/robot_ui.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,10 @@ def bind(self, key) -> CommandQueue:
8181
return self.key_commands[key]
8282

8383
async def _connect_and_run(self):
84-
scanner = BleakScanner()
8584
self.update_status(f'scanning for {self.robot.display_name} ...')
86-
devices = await scanner.discover(timeout=2.0, return_adv=False)
85+
device = await BleakScanner.find_device_by_name(self.robot.name, timeout=10.0)
8786

8887
self.update_status(f'connecting to {self.robot.display_name} ...')
89-
device = None
90-
for d in devices:
91-
if d.name is not None and d.name.lower() == self.robot.name:
92-
device = d
93-
break
9488

9589
if device is None:
9690
self.update_status(f"device {self.robot.name} not found. Quit and try again.")
@@ -129,6 +123,9 @@ def _button_handler_callback(characteristic: BleakGATTCharacteristic, data: byte
129123

130124
await self.execute(commands)
131125

126+
if self.robot.button_a_queue.empty() and self.robot.button_b_queue.empty() and not self.key_commands:
127+
self.exit()
128+
132129
async def execute(self, commands):
133130
if self.running == 1: return
134131

@@ -138,8 +135,11 @@ async def execute(self, commands):
138135
# self.update_status(f"executing {command.__class__.__name__} ...")
139136
await command.execute(self.client)
140137

141-
self.update_status('idle')
142-
self.running = 0
138+
if not self.key_commands and self.robot.button_a_queue.empty() and self.robot.button_b_queue.empty():
139+
return
140+
else:
141+
self.update_status('idle')
142+
self.running = 0
143143

144144
async def clear(self):
145145
self.running = 1

0 commit comments

Comments
 (0)