libraspike-art-python 0.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Wataru Taniguchi <wataru@taniguchifamily.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.1
2
+ Name: libraspike-art-python
3
+ Version: 0.0.3
4
+ Summary: Python CFFI Bindings for libraspike-art
5
+ Author: Wataru Taniguchi
6
+ Author-email: wataru@taniguchifamily.com
7
+ License: MIT
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: Implementation :: CPython
10
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ ## Python CFFI Bindings for libraspike-art
15
+
16
+ # Installation
17
+
18
+ Enable use of libraspike-art by following the direction [here](https://github.com/ETrobocon/libraspike-art/tree/main).
19
+
20
+ If you are on a modern Linux you will probably want to create a venv:
21
+
22
+ python3 -m venv vpython3
23
+ source vpython3/bin/activate
24
+
25
+ or:
26
+
27
+ pypy3 -m venv vpypy3
28
+ source vpypy3/bin/activate
29
+
30
+ Build the bindings and install libraspike-art-python package:
31
+
32
+ pip install libraspike-art-python
@@ -0,0 +1,19 @@
1
+ ## Python CFFI Bindings for libraspike-art
2
+
3
+ # Installation
4
+
5
+ Enable use of libraspike-art by following the direction [here](https://github.com/ETrobocon/libraspike-art/tree/main).
6
+
7
+ If you are on a modern Linux you will probably want to create a venv:
8
+
9
+ python3 -m venv vpython3
10
+ source vpython3/bin/activate
11
+
12
+ or:
13
+
14
+ pypy3 -m venv vpypy3
15
+ source vpypy3/bin/activate
16
+
17
+ Build the bindings and install libraspike-art-python package:
18
+
19
+ pip install libraspike-art-python
@@ -0,0 +1,254 @@
1
+ from _libraspike_art import ffi, lib
2
+ from enum import IntEnum
3
+ from typing import Tuple
4
+ import sys
5
+ from .version import __version__
6
+
7
+ print("LIBRASPIKE-ART STATIC "+__version__+" LOADED", file=sys.stderr)
8
+
9
+ class pbio_error(IntEnum):
10
+ SUCCESS = lib.PBIO_SUCCESS
11
+ FAILED = lib.PBIO_ERROR_FAILED
12
+ INVALID_ARG = lib.PBIO_ERROR_INVALID_ARG
13
+ IO = lib.PBIO_ERROR_IO
14
+ BUSY = lib.PBIO_ERROR_BUSY
15
+ NO_DEV = lib.PBIO_ERROR_NO_DEV
16
+ NOT_IMPLEMENTED = lib.PBIO_ERROR_NOT_IMPLEMENTED
17
+ NOT_SUPPORTED = lib.PBIO_ERROR_NOT_SUPPORTED
18
+ AGAIN = lib.PBIO_ERROR_AGAIN
19
+ INVALID_OP = lib.PBIO_ERROR_INVALID_OP
20
+ TIMEDOUT = lib.PBIO_ERROR_TIMEDOUT
21
+ CANCELED = lib.PBIO_ERROR_CANCELED
22
+
23
+ class pbio_port(IntEnum):
24
+ ID_A = lib.PBIO_PORT_ID_A
25
+ ID_B = lib.PBIO_PORT_ID_B
26
+ ID_C = lib.PBIO_PORT_ID_C
27
+ ID_D = lib.PBIO_PORT_ID_D
28
+ ID_E = lib.PBIO_PORT_ID_E
29
+ ID_F = lib.PBIO_PORT_ID_F
30
+
31
+ def PBIO_COLOR_ENCODE(h, s, v):
32
+ return ((h // 30) << 3) | ((s // 51) << 2) | (v // 34)
33
+
34
+ class pbio_color(IntEnum):
35
+ NONE = PBIO_COLOR_ENCODE(180, 0, 0)
36
+ BLACK = PBIO_COLOR_ENCODE(0, 0, 0)
37
+ GRAY = PBIO_COLOR_ENCODE(0, 0, 50)
38
+ WHITE = PBIO_COLOR_ENCODE(0, 0, 100)
39
+ RED = PBIO_COLOR_ENCODE(0, 100, 100)
40
+ BROWN = PBIO_COLOR_ENCODE(30, 100, 50)
41
+ ORANGE = PBIO_COLOR_ENCODE(30, 100, 100)
42
+ YELLOW = PBIO_COLOR_ENCODE(60, 100, 100)
43
+ GREEN = PBIO_COLOR_ENCODE(120, 100, 100)
44
+ SPRING_GREEN = PBIO_COLOR_ENCODE(150, 100, 100)
45
+ CYAN = PBIO_COLOR_ENCODE(180, 100, 100)
46
+ BLUE = PBIO_COLOR_ENCODE(240, 100, 100)
47
+ VIOLET = PBIO_COLOR_ENCODE(270, 100, 100)
48
+ MAGENTA = PBIO_COLOR_ENCODE(300, 100, 100)
49
+
50
+ class hub_button(IntEnum):
51
+ LEFT = lib.HUB_BUTTON_LEFT
52
+ CENTER = lib.HUB_BUTTON_CENTER
53
+ RIGHT = lib.HUB_BUTTON_RIGHT
54
+ BT = lib.HUB_BUTTON_BT
55
+
56
+ class sound(IntEnum):
57
+ MANUAL_STOP = -1
58
+ NOTE_C4 = 261.63
59
+ NOTE_CS4 = 277.18
60
+ NOTE_D4 = 293.66
61
+ NOTE_DS4 = 311.13
62
+ NOTE_E4 = 329.63
63
+ NOTE_F4 = 349.23
64
+ NOTE_FS4 = 369.99
65
+ NOTE_G4 = 392.00
66
+ NOTE_GS4 = 415.30
67
+ NOTE_A4 = 440.00
68
+ NOTE_AS4 = 466.16
69
+ NOTE_B4 = 493.88
70
+ NOTE_C5 = 523.25
71
+ NOTE_CS5 = 554.37
72
+ NOTE_D5 = 587.33
73
+ NOTE_DS5 = 622.25
74
+ NOTE_E5 = 659.25
75
+ NOTE_F5 = 698.46
76
+ NOTE_FS5 = 739.99
77
+ NOTE_G5 = 783.99
78
+ NOTE_GS5 = 830.61
79
+ NOTE_A5 = 880.00
80
+ NOTE_AS5 = 932.33
81
+ NOTE_B5 = 987.77
82
+ NOTE_C6 =1046.50
83
+ NOTE_CS6 =1108.73
84
+ NOTE_D6 =1174.66
85
+ NOTE_DS6 =1244.51
86
+ NOTE_E6 =1318.51
87
+ NOTE_F6 =1396.91
88
+ NOTE_FS6 =1479.98
89
+ NOTE_G6 =1567.98
90
+ NOTE_GS6 =1661.22
91
+ NOTE_A6 =1760.00
92
+ NOTE_AS6 =1864.66
93
+ NOTE_B6 =1975.53
94
+
95
+ class pup_direction(IntEnum):
96
+ CLOCKWISE = lib.PUP_DIRECTION_CLOCKWISE
97
+ COUNTERCLOCKWISE = lib.PUP_DIRECTION_COUNTERCLOCKWISE
98
+
99
+ def raspike_open_usb_communication(device_name: str) -> ffi.CData:
100
+ desc = lib.raspike_open_usb_communication(device_name.encode())
101
+ return desc if desc != ffi.NULL else None
102
+
103
+ def raspike_prot_init(desc: ffi.CData) -> int:
104
+ return lib.raspike_prot_init(desc)
105
+ def raspike_prot_receive() -> int:
106
+ return lib.raspike_prot_receive()
107
+ def raspike_prot_shutdown() -> int:
108
+ return lib.raspike_prot_shutdown()
109
+
110
+ def hub_system_shutdown() -> None:
111
+ lib.hub_system_shutdown()
112
+
113
+ def hub_imu_init() -> pbio_error:
114
+ return lib.hub_imu_init()
115
+ def hub_imu_get_acceleration() -> Tuple[float, float, float]:
116
+ accel = ffi.new("float[3]")
117
+ lib.hub_imu_get_acceleration(accel)
118
+ return accel[0], accel[1], accel[2]
119
+ def hub_imu_get_angular_velocity() -> Tuple[float, float, float]:
120
+ angv = ffi.new("float[3]")
121
+ lib.hub_imu_get_angular_velocity(angv)
122
+ return angv[0], angv[1], angv[2]
123
+ def hub_imu_get_temperature() -> float:
124
+ return lib.hub_imu_get_temperature()
125
+
126
+ def hub_display_orientation(up) -> pbio_error:
127
+ return lib.hub_display_orientation(up)
128
+ def hub_display_off() -> pbio_error:
129
+ return lib.hub_display_off()
130
+ def hub_display_pixel(row, column, brightness) -> pbio_error:
131
+ return lib.hub_display_pixel(row, column, brightness)
132
+ #ToDo: pbio_error_t hub_display_image(uint8_t* image);
133
+ def hub_display_number(num: int) -> pbio_error:
134
+ return lib.hub_display_number(num)
135
+ def hub_display_char(c: str) -> pbio_error:
136
+ return lib.hub_display_char(c.encode())
137
+ def hub_display_text(text: str, on: int, off: int) -> pbio_error:
138
+ return lib.hub_display_text(text.encode(), on, off)
139
+ def hub_display_text_scroll(text: str, delay: int) -> pbio_error:
140
+ return lib.hub_display_text_scroll(text.encode(), delay)
141
+
142
+ def hub_light_on_hsv(h: int, s: int, v:int) -> pbio_error:
143
+ hsv = ffi.new("pbio_color_hsv_t *")
144
+ hsv.h = h
145
+ hsv.s = s
146
+ hsv.v = v
147
+ return lib.hub_light_on_hsv(hsv)
148
+ def hub_light_on_color(color: pbio_color) -> pbio_error:
149
+ return lib.hub_light_on_color(color)
150
+ def hub_light_off() -> pbio_error:
151
+ return lib.hub_light_off()
152
+
153
+ def hub_speaker_set_volume(volume: int) -> None:
154
+ lib.hub_speaker_set_volume(volume)
155
+ def hub_speaker_play_tone(frequency: int, duration: int) -> None:
156
+ lib.hub_speaker_play_tone(frequency, duration)
157
+ def hub_speaker_stop() -> None:
158
+ lib.hub_speaker_stop()
159
+
160
+ def hub_battery_get_voltage() -> int:
161
+ return lib.hub_battery_get_voltage()
162
+ def hub_battery_get_current() -> int:
163
+ return lib.hub_battery_get_current()
164
+
165
+ def hub_button_is_pressed(button: hub_button) -> bool:
166
+ pressed = ffi.new("hub_button_t *")
167
+ error = lib.hub_button_is_pressed(pressed)
168
+ if error == pbio_error.SUCCESS:
169
+ return pressed[0] & button
170
+ else:
171
+ return False
172
+
173
+ def pup_ultrasonic_sensor_get_device(port: pbio_port) -> ffi.CData:
174
+ pdev = lib.pup_ultrasonic_sensor_get_device(port)
175
+ return pdev if pdev != ffi.NULL else None
176
+ def pup_ultrasonic_sensor_distance(pdev: ffi.CData) -> int:
177
+ return lib.pup_ultrasonic_sensor_distance(pdev)
178
+ def pup_ultrasonic_sensor_presence(pdev: ffi.CData) -> bool:
179
+ return lib.pup_ultrasonic_sensor_presence(pdev)
180
+
181
+ def pup_force_sensor_get_device(port: pbio_port) -> ffi.CData:
182
+ pdev = lib.pup_force_sensor_get_device(port)
183
+ return pdev if pdev != ffi.NULL else None
184
+ def pup_force_sensor_force(pdev: ffi.CData) -> float:
185
+ return lib.pup_force_sensor_force(pdev)
186
+ def pup_force_sensor_distance(pdev: ffi.CData) -> float:
187
+ return lib.pup_force_sensor_distance(pdev)
188
+ def pup_force_sensor_pressed(pdev: ffi.CData, force: float) -> bool:
189
+ return lib.pup_force_sensor_pressed(pdev, force)
190
+ def pup_force_sensor_touched(pdev: ffi.CData) -> bool:
191
+ return lib.pup_force_sensor_touched(pdev)
192
+
193
+
194
+ def pup_color_sensor_get_device(port: pbio_port) -> ffi.CData:
195
+ pdev = lib.pup_color_sensor_get_device(port)
196
+ return pdev if pdev != ffi.NULL else None
197
+ def pup_color_sensor_rgb(pdev: ffi.CData) -> Tuple[int, int, int]:
198
+ rgb = lib.pup_color_sensor_rgb(pdev)
199
+ if rgb != ffi.NULL:
200
+ return rgb.r, rgb.g, rgb.b
201
+ else:
202
+ return None
203
+ def pup_color_sensor_color(pdev: ffi.CData, surface: bool) -> pbio_color:
204
+ hsv = lib.pup_color_sensor_color(pdev, surface)
205
+ if hsv != ffi.NULL:
206
+ return PBIO_COLOR_ENCODE(hsv.h, hsv.s, hsv.v)
207
+ else:
208
+ return None
209
+ def pup_color_sensor_hsv(pdev: ffi.CData, surface: bool) -> Tuple[int, int, int]:
210
+ hsv = lib.pup_color_sensor_hsv(pdev, surface)
211
+ if hsv != ffi.NULL:
212
+ return hsv.h, hsv.s, hsv.v
213
+ else:
214
+ return None
215
+ def pup_color_sensor_reflection(pdev: ffi.CData):
216
+ return lib.pup_color_sensor_reflection(pdev)
217
+ def pup_color_sensor_ambient(pdev: ffi.CData):
218
+ return lib.pup_color_sensor_ambient(pdev)
219
+ def pup_color_sensor_light_set(pdev: ffi.CData, bv1: int, bv2: int, bv3: int) -> pbio_error:
220
+ return lib.pup_color_sensor_light_set(pdev, bv1, bv2, bv3)
221
+ def pup_color_sensor_light_on(pdev: ffi.CData) -> pbio_error:
222
+ return lib.pup_color_sensor_light_on(pdev)
223
+ def pup_color_sensor_light_off(pdev: ffi.CData) -> pbio_error:
224
+ return lib.pup_color_sensor_light_off(pdev)
225
+ #ToDo: pup_color_hsv_t *pup_color_sensor_detectable_colors(int32_t size, pup_color_hsv_t *colors);
226
+
227
+ def pup_motor_get_device(port: pbio_port) -> ffi.CData:
228
+ return lib.pup_motor_get_device(port)
229
+ def pup_motor_setup(motor: ffi.CData, positive_direction: pup_direction, reset_count: bool) -> pbio_error:
230
+ return lib.pup_motor_setup(motor, positive_direction, reset_count)
231
+ def pup_motor_reset_count(motor: ffi.CData) -> pbio_error:
232
+ return lib.pup_motor_reset_count(motor)
233
+ def pup_motor_get_count(motor: ffi.CData) -> int:
234
+ return lib.pup_motor_get_count(motor)
235
+ def pup_motor_get_speed(motor: ffi.CData) -> int:
236
+ return lib.pup_motor_get_speed(motor)
237
+ def pup_motor_set_speed(motor: ffi.CData, speed: int) -> pbio_error:
238
+ return lib.pup_motor_set_speed(motor, speed)
239
+ def pup_motor_get_power(motor: ffi.CData) -> int:
240
+ return lib.pup_motor_get_power(motor)
241
+ def pup_motor_set_power(motor: ffi.CData, power: int) -> pbio_error:
242
+ return lib.pup_motor_set_power(motor, power)
243
+ def pup_motor_stop(motor: ffi.CData) -> pbio_error:
244
+ return lib.pup_motor_stop(motor)
245
+ def pup_motor_brake(motor: ffi.CData) -> pbio_error:
246
+ return lib.pup_motor_brake(motor)
247
+ def pup_motor_hold(motor: ffi.CData) -> pbio_error:
248
+ return lib.pup_motor_hold(motor)
249
+ def pup_motor_is_stalled(motor: ffi.CData) -> bool:
250
+ return lib.pup_motor_is_stalled(motor)
251
+ def pup_motor_set_duty_limit(motor: ffi.CData, duty_limit: int) -> int:
252
+ return lib.pup_motor_set_duty_limit(motor, duty_limit)
253
+ def pup_motor_restore_duty_limit(motor: ffi.CData, old_value: int) -> None:
254
+ pup_motor_restore_duty_limit(motor, old_value)
@@ -0,0 +1,216 @@
1
+ from cffi import FFI
2
+ import subprocess
3
+ from os import path
4
+
5
+ LIB_SOURCE = './libraspike-art/'
6
+
7
+ def clone_git():
8
+ return subprocess.run(['git', 'clone', 'https://github.com/ETrobocon/libraspike-art.git'], text=True,
9
+ stdout=subprocess.PIPE).stdout.strip()
10
+
11
+ def make_lib():
12
+ return subprocess.run(['make'], cwd=(LIB_SOURCE + 'build/obj-libraspike-art'), text=True,
13
+ stdout=subprocess.PIPE).stdout.strip()
14
+
15
+ ffibuilder = FFI()
16
+
17
+ if not path.isdir(LIB_SOURCE):
18
+ clone_git()
19
+ if not path.isfile(LIB_SOURCE + 'lib/libraspike-art.a'):
20
+ make_lib()
21
+
22
+ # include header files for libraspike-art
23
+ ffibuilder.set_source("_libraspike_art",
24
+ """
25
+ #include "raspike_com.h"
26
+ #include "raspike_protocol_api.h"
27
+ #include "spike/pup/motor.h"
28
+ #include "spike/pup/colorsensor.h"
29
+ #include "spike/pup/forcesensor.h"
30
+ #include "spike/pup/ultrasonicsensor.h"
31
+ #include "spike/hub/system.h"
32
+ #include "spike/hub/light.h"
33
+ #include "spike/hub/imu.h"
34
+ #include "spike/hub/display.h"
35
+ #include "spike/hub/button.h"
36
+ #include "spike/hub/battery.h"
37
+ #include "spike/hub/speaker.h"
38
+ """,
39
+ include_dirs=[LIB_SOURCE + 'include/',
40
+ LIB_SOURCE + 'drivers/include/',
41
+ LIB_SOURCE + 'drivers/',
42
+ LIB_SOURCE + 'external/libpybricks/lib/pbio/include/'],
43
+ extra_link_args=[],
44
+ library_dirs=[LIB_SOURCE + 'lib/'],
45
+ libraries=['raspike-art'])
46
+
47
+ # descrption of C functions to invoke from Python
48
+ ffibuilder.cdef(
49
+ """
50
+ /* raspike_com.h */
51
+ struct _RPComDescriptor;
52
+ typedef struct _RPComDescriptor RPComDescriptor;
53
+ RPComDescriptor *raspike_open_usb_communication(const char *device_name);
54
+
55
+ /* raspike_protocol_api.h */
56
+ int raspike_prot_init(RPComDescriptor *desc);
57
+ int raspike_prot_receive(void);
58
+ int raspike_prot_shutdown(void);
59
+
60
+ /* pbio/error.h */
61
+ typedef enum {
62
+ PBIO_SUCCESS, /**< No error */
63
+ PBIO_ERROR_FAILED, /**< Unspecified error (used when no other error code fits) */
64
+ PBIO_ERROR_INVALID_ARG, /**< Invalid argument */
65
+ PBIO_ERROR_IO, /**< General I/O error */
66
+ PBIO_ERROR_BUSY, /**< Device or resource is busy */
67
+ PBIO_ERROR_NO_DEV, /**< Device is not connected */
68
+ PBIO_ERROR_NOT_IMPLEMENTED, /**< Feature is not yet implemented */
69
+ PBIO_ERROR_NOT_SUPPORTED, /**< Feature is not supported on this device */
70
+ PBIO_ERROR_AGAIN, /**< Function should be called again later */
71
+ PBIO_ERROR_INVALID_OP, /**< Operation is not permitted in the current state */
72
+ PBIO_ERROR_TIMEDOUT, /**< The operation has timed out */
73
+ PBIO_ERROR_CANCELED /**< The operation was canceled */
74
+ } pbio_error_t;
75
+
76
+ /* pbio/port.h */
77
+ typedef enum {
78
+ PBIO_PORT_ID_A = 'A', /**< I/O port labeled as "A" */
79
+ PBIO_PORT_ID_B = 'B', /**< I/O port labeled as "B" */
80
+ PBIO_PORT_ID_C = 'C', /**< I/O port labeled as "C" */
81
+ PBIO_PORT_ID_D = 'D', /**< I/O port labeled as "D" */
82
+ PBIO_PORT_ID_E = 'E', /**< I/O port labeled as "C" */
83
+ PBIO_PORT_ID_F = 'F', /**< I/O port labeled as "F" */
84
+ } pbio_port_id_t;
85
+
86
+ /* pbio/color.h */
87
+ typedef enum {...} pbio_color_t;
88
+ typedef struct {
89
+ /** The hue component. 0 to 359 degrees. */
90
+ uint16_t h;
91
+ /** The saturation component. 0 to 100 percent. */
92
+ uint8_t s;
93
+ /** The value component. 0 to 100 percent. */
94
+ uint8_t v;
95
+ } pbio_color_hsv_t;
96
+
97
+ /* pbio/button.h */
98
+ typedef enum _pbio_button_flags_t {
99
+ PBIO_BUTTON_LEFT_DOWN = 1 << 1,
100
+ PBIO_BUTTON_DOWN = 1 << 2,
101
+ PBIO_BUTTON_RIGHT_DOWN = 1 << 3,
102
+ PBIO_BUTTON_LEFT = 1 << 4,
103
+ PBIO_BUTTON_CENTER = 1 << 5,
104
+ PBIO_BUTTON_RIGHT = 1 << 6,
105
+ PBIO_BUTTON_LEFT_UP = 1 << 7,
106
+ PBIO_BUTTON_UP = 1 << 8,
107
+ PBIO_BUTTON_RIGHT_UP = 1 << 9,
108
+ } pbio_button_flags_t;
109
+
110
+ /* pbio/servo.h */
111
+ struct _pbio_servo_t;
112
+ typedef struct _pbio_servo_t pbio_servo_t;
113
+
114
+ /* spike/hub/system.h */
115
+ void hub_system_shutdown(void);
116
+
117
+ /* spike/hub/imu.h */
118
+ pbio_error_t hub_imu_init(void);
119
+ void hub_imu_get_acceleration(float accel[3]);
120
+ void hub_imu_get_angular_velocity(float angv[3]);
121
+ float hub_imu_get_temperature(void);
122
+
123
+ /* spike/hub/display.h */
124
+ pbio_error_t hub_display_orientation(uint8_t up);
125
+ pbio_error_t hub_display_off(void);
126
+ pbio_error_t hub_display_pixel(uint8_t row, uint8_t column, uint8_t brightness);
127
+ pbio_error_t hub_display_image(uint8_t* image);
128
+ pbio_error_t hub_display_number(const int8_t num);
129
+ pbio_error_t hub_display_char(const char c);
130
+ pbio_error_t hub_display_text(const char* text, uint32_t on, uint32_t off);
131
+ pbio_error_t hub_display_text_scroll(const char* text, uint32_t delay);
132
+
133
+ /* spike/hub/light.h */
134
+ pbio_error_t hub_light_on_hsv(const pbio_color_hsv_t *hsv);
135
+ pbio_error_t hub_light_on_color(pbio_color_t color);
136
+ pbio_error_t hub_light_off(void);
137
+
138
+ /* spike/hub/speaker.h */
139
+ void hub_speaker_set_volume(uint8_t volume);
140
+ void hub_speaker_play_tone(uint16_t frequency, int32_t duration);
141
+ void hub_speaker_stop(void);
142
+
143
+ /* spike/hub/battery.h */
144
+ uint16_t hub_battery_get_voltage(void);
145
+ uint16_t hub_battery_get_current(void);
146
+
147
+ /* spike/hub/button.h */
148
+ typedef enum _hub_button_t {
149
+ HUB_BUTTON_LEFT = PBIO_BUTTON_LEFT,
150
+ HUB_BUTTON_CENTER = PBIO_BUTTON_CENTER,
151
+ HUB_BUTTON_RIGHT = PBIO_BUTTON_RIGHT,
152
+ HUB_BUTTON_BT = PBIO_BUTTON_RIGHT_UP,
153
+ } hub_button_t;
154
+ pbio_error_t hub_button_is_pressed(hub_button_t *pressed);
155
+
156
+ /* spike/pup_device.h */
157
+ struct _pup_device_t;
158
+ typedef struct _pup_device_t pup_device_t;
159
+
160
+ /* spike/pup/ultrasonicsensor.h */
161
+ pup_device_t *pup_ultrasonic_sensor_get_device(pbio_port_id_t port);
162
+ int32_t pup_ultrasonic_sensor_distance(pup_device_t *pdev);
163
+ bool pup_ultrasonic_sensor_presence(pup_device_t *pdev);
164
+
165
+ /* spike/pup/forcesensor.h */
166
+ pup_device_t *pup_force_sensor_get_device(pbio_port_id_t port);
167
+ float pup_force_sensor_force(pup_device_t *pdev);
168
+ float pup_force_sensor_distance(pup_device_t *pdev);
169
+ bool pup_force_sensor_pressed(pup_device_t *pdev, float force);
170
+ bool pup_force_sensor_touched(pup_device_t *pdev);
171
+
172
+ /* spike/pup/colorsensor.h */
173
+ pup_device_t *pup_color_sensor_get_device(pbio_port_id_t port);
174
+ typedef struct {
175
+ uint16_t r, g, b;
176
+ } pup_color_rgb_t;
177
+ pup_color_rgb_t pup_color_sensor_rgb(pup_device_t *pdev);
178
+ typedef pbio_color_hsv_t pup_color_hsv_t;
179
+ pup_color_hsv_t pup_color_sensor_color(pup_device_t *pdev, bool surface);
180
+ pup_color_hsv_t pup_color_sensor_hsv(pup_device_t *pdev, bool surface);
181
+ int32_t pup_color_sensor_reflection(pup_device_t *pdev);
182
+ int32_t pup_color_sensor_ambient(pup_device_t *pdev);
183
+ pbio_error_t pup_color_sensor_light_set(pup_device_t *pdev,
184
+ int32_t bv1, int32_t bv2, int32_t bv3);
185
+ pbio_error_t pup_color_sensor_light_on(pup_device_t *pdev);
186
+ pbio_error_t pup_color_sensor_light_off(pup_device_t *pdev);
187
+ pup_color_hsv_t *pup_color_sensor_detectable_colors(int32_t size, pup_color_hsv_t *colors);
188
+
189
+ /* /spike/pup/motor.h */
190
+ typedef pbio_servo_t pup_motor_t;
191
+ typedef enum {
192
+ PBIO_DIRECTION_CLOCKWISE, /**< Positive means clockwise. */
193
+ PBIO_DIRECTION_COUNTERCLOCKWISE, /**< Positive means counterclockwise. */
194
+ } pbio_direction_t;
195
+ typedef enum {
196
+ PUP_DIRECTION_CLOCKWISE = PBIO_DIRECTION_CLOCKWISE,
197
+ PUP_DIRECTION_COUNTERCLOCKWISE = PBIO_DIRECTION_COUNTERCLOCKWISE,
198
+ } pup_direction_t;
199
+ pup_motor_t *pup_motor_get_device(pbio_port_id_t port);
200
+ pbio_error_t pup_motor_setup(pup_motor_t *motor, pup_direction_t positive_direction, bool reset_count);
201
+ pbio_error_t pup_motor_reset_count(pup_motor_t *motor);
202
+ int32_t pup_motor_get_count(pup_motor_t *motor);
203
+ int32_t pup_motor_get_speed(pup_motor_t *motor);
204
+ pbio_error_t pup_motor_set_speed(pup_motor_t *motor, int speed);
205
+ int32_t pup_motor_get_power(pup_motor_t *motor);
206
+ pbio_error_t pup_motor_set_power(pup_motor_t *motor, int power);
207
+ pbio_error_t pup_motor_stop(pup_motor_t *motor);
208
+ pbio_error_t pup_motor_brake(pup_motor_t *motor);
209
+ pbio_error_t pup_motor_hold(pup_motor_t *motor);
210
+ bool pup_motor_is_stalled(pup_motor_t *motor);
211
+ int32_t pup_motor_set_duty_limit(pup_motor_t *motor, int duty_limit);
212
+ void pup_motor_restore_duty_limit(pup_motor_t *motor, int old_value);
213
+ """)
214
+
215
+ if __name__ == "__main__":
216
+ ffibuilder.compile(verbose=True)
@@ -0,0 +1 @@
1
+ __version__ = '0.0.3'
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.1
2
+ Name: libraspike-art-python
3
+ Version: 0.0.3
4
+ Summary: Python CFFI Bindings for libraspike-art
5
+ Author: Wataru Taniguchi
6
+ Author-email: wataru@taniguchifamily.com
7
+ License: MIT
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: Implementation :: CPython
10
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ ## Python CFFI Bindings for libraspike-art
15
+
16
+ # Installation
17
+
18
+ Enable use of libraspike-art by following the direction [here](https://github.com/ETrobocon/libraspike-art/tree/main).
19
+
20
+ If you are on a modern Linux you will probably want to create a venv:
21
+
22
+ python3 -m venv vpython3
23
+ source vpython3/bin/activate
24
+
25
+ or:
26
+
27
+ pypy3 -m venv vpypy3
28
+ source vpypy3/bin/activate
29
+
30
+ Build the bindings and install libraspike-art-python package:
31
+
32
+ pip install libraspike-art-python
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.cfg
5
+ setup.py
6
+ libraspike_art_python/__init__.py
7
+ libraspike_art_python/ffi_build.py
8
+ libraspike_art_python/version.py
9
+ libraspike_art_python.egg-info/PKG-INFO
10
+ libraspike_art_python.egg-info/SOURCES.txt
11
+ libraspike_art_python.egg-info/dependency_links.txt
12
+ libraspike_art_python.egg-info/requires.txt
13
+ libraspike_art_python.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ _libraspike_art
2
+ libraspike_art_python
@@ -0,0 +1,6 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools",
4
+ "wheel",
5
+ ]
6
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,27 @@
1
+ [metadata]
2
+ name = libraspike-art-python
3
+ version = attr: libraspike_art_python.version.__version__
4
+ description = Python CFFI Bindings for libraspike-art
5
+ long_description = file: README.md
6
+ long_description_content_type = text/markdown
7
+ license = MIT
8
+ license_file = LICENSE
9
+ author = Wataru Taniguchi
10
+ author_email = wataru@taniguchifamily.com
11
+ classifiers =
12
+ Programming Language :: Python :: 3
13
+ Programming Language :: Python :: Implementation :: CPython
14
+ Programming Language :: Python :: Implementation :: PyPy
15
+
16
+ [options]
17
+ packages = libraspike_art_python
18
+ setup_requires =
19
+ cffi >= 1.17.1
20
+ setuptools
21
+ install_requires =
22
+ cffi >= 1.17.1
23
+
24
+ [egg_info]
25
+ tag_build =
26
+ tag_date = 0
27
+
@@ -0,0 +1,5 @@
1
+ from setuptools import setup
2
+
3
+ setup(
4
+ cffi_modules=["libraspike_art_python/ffi_build.py:ffibuilder"]
5
+ )