• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pybricks / pybricks-micropython / 18090950977

29 Sep 2025 08:31AM UTC coverage: 59.39%. First build
18090950977

Pull #389

github

laurensvalk
pbio/drv/bluetooth: Shut down gracefully.

Before the Bluetooth overhaul, we were just powering down. In the recent commits, this was not yet implemented, so the hub would stay connected or keep advertising once turned off and charging.

Poweroff is now back, but we also gracefully disconnect first to be nice to Pybricks Code.
Pull Request #389: Improve Bluetooth de-initialization

8 of 48 new or added lines in 10 files covered. (16.67%)

4228 of 7119 relevant lines covered (59.39%)

20567594.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pybricks/parameters/pb_type_button.c
1
// SPDX-License-Identifier: MIT
2
// Copyright (c) 2018-2023 The Pybricks Authors
3

4
#include "py/mpconfig.h"
5

6
#if PYBRICKS_PY_PARAMETERS
7

8
#if PYBRICKS_PY_PARAMETERS_BUTTON
9

10
#include <pbio/button.h>
11

12
#include "py/obj.h"
13
#include "py/runtime.h"
14

15
#include <pybricks/parameters/pb_type_button.h>
16

17
#include <pybricks/util_mp/pb_type_enum.h>
18
#include <pybricks/util_mp/pb_obj_helper.h>
19

20
#include <pybricks/util_pb/pb_error.h>
21

22
static const qstr buttons[] = {
23
    MP_QSTR_LEFT,
24
    MP_QSTR_RIGHT,
25
    MP_QSTR_CENTER,
26
    MP_QSTR_LEFT_PLUS,
27
    MP_QSTR_LEFT_MINUS,
28
    MP_QSTR_RIGHT_PLUS,
29
    MP_QSTR_RIGHT_MINUS,
30
    #if !PYBRICKS_PY_PARAMETERS_BUTTON_REMOTE_ONLY
31
    MP_QSTR_UP,
32
    MP_QSTR_DOWN,
33
    MP_QSTR_LEFT_UP,
34
    MP_QSTR_LEFT_DOWN,
35
    MP_QSTR_RIGHT_UP,
36
    MP_QSTR_RIGHT_DOWN,
37
    MP_QSTR_BEACON,
38
    MP_QSTR_BLUETOOTH,
39
    MP_QSTR_A,
40
    MP_QSTR_B,
41
    MP_QSTR_X,
42
    MP_QSTR_Y,
43
    MP_QSTR_LB,
44
    MP_QSTR_RB,
45
    MP_QSTR_VIEW,
46
    MP_QSTR_MENU,
47
    MP_QSTR_GUIDE,
48
    MP_QSTR_LJ,
49
    MP_QSTR_RJ,
50
    MP_QSTR_UPLOAD,
51
    MP_QSTR_P1,
52
    MP_QSTR_P2,
53
    MP_QSTR_P3,
54
    MP_QSTR_P4,
55
    #endif
56
};
57

58
extern const mp_obj_type_t pb_type_button_;
59

60
static void pb_type_button_print(const mp_print_t *print,  mp_obj_t self_in, mp_print_kind_t kind) {
×
61
    pb_obj_button_t *self = MP_OBJ_TO_PTR(self_in);
×
62
    mp_printf(print, self->name == pb_type_button.name ? "%q" : "%q.%q", MP_QSTR_Button, self->name);
×
63
}
×
64

65
mp_obj_t pb_type_button_new(qstr name) {
×
66
    pb_obj_button_t *result = mp_obj_malloc(pb_obj_button_t, &pb_type_button_);
×
67
    result->name = name;
×
68
    return MP_OBJ_FROM_PTR(result);
×
69
}
70

71
static void pb_type_button_attribute_handler(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
×
72

73
    // Write and delete not supported. Re-reading from an instance also not supported.
74
    if (dest[0] != MP_OBJ_NULL || MP_OBJ_TO_PTR(self_in) != &pb_type_button) {
×
75
        return;
76
    }
77

78
    // Allocate new button object if the attribute is a valid button.
79
    for (size_t i = 0; i < MP_ARRAY_SIZE(buttons); i++) {
×
80
        if (attr == buttons[i]) {
×
81
            dest[0] = pb_type_button_new(attr);
×
82
            return;
×
83
        }
84
    }
85
}
86

87
static mp_obj_t pb_type_button_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
×
88

89
    // Only equality comparison is supported.
90
    if (op != MP_BINARY_OP_EQUAL) {
×
91
        return MP_OBJ_NULL;
92
    }
93
    if (!mp_obj_is_type(lhs_in, &pb_type_button_) || !mp_obj_is_type(rhs_in, &pb_type_button_)) {
×
94
        return mp_const_false;
95
    }
96

97
    pb_obj_button_t *lhs = MP_OBJ_TO_PTR(lhs_in);
×
98
    pb_obj_button_t *rhs = MP_OBJ_TO_PTR(rhs_in);
×
99
    return mp_obj_new_bool(lhs->name == rhs->name);
×
100
}
101

102
MP_DEFINE_CONST_OBJ_TYPE(pb_type_button_,
103
    MP_QSTR_Button,
104
    MP_TYPE_FLAG_NONE,
105
    print, pb_type_button_print,
106
    attr, pb_type_button_attribute_handler,
107
    binary_op, pb_type_button_binary_op
108
    );
109

110
// The exposed 'type' object is in fact an instance of the type, so we can have
111
// an attribute handler for the type that creates new button objects.
112
const pb_obj_button_t pb_type_button = {
113
    {&pb_type_button_},
114
    .name = MP_QSTRnull
115
};
116

117
#if PYBRICKS_PY_COMMON_KEYPAD_HUB_BUTTONS > 1
118
pbio_button_flags_t pb_type_button_get_button_flag(mp_obj_t obj) {
119
    pb_assert_type(obj, &pb_type_button_);
120
    pb_obj_button_t *button = MP_OBJ_TO_PTR(obj);
121

122
    switch (button->name) {
123
        case MP_QSTR_UP:
124
        case MP_QSTR_BEACON:
125
            return PBIO_BUTTON_UP;
126
        case MP_QSTR_DOWN:
127
            return PBIO_BUTTON_DOWN;
128
        case MP_QSTR_LEFT:
129
            return PBIO_BUTTON_LEFT;
130
        case MP_QSTR_RIGHT:
131
            return PBIO_BUTTON_RIGHT;
132
        case MP_QSTR_CENTER:
133
            return PBIO_BUTTON_CENTER;
134
        case MP_QSTR_LEFT_UP:
135
        case MP_QSTR_LEFT_PLUS:
136
            return PBIO_BUTTON_LEFT_UP;
137
        case MP_QSTR_LEFT_DOWN:
138
        case MP_QSTR_LEFT_MINUS:
139
            return PBIO_BUTTON_LEFT_DOWN;
140
        case MP_QSTR_RIGHT_UP:
141
        case MP_QSTR_RIGHT_PLUS:
142
        case MP_QSTR_BLUETOOTH:
143
            return PBIO_BUTTON_RIGHT_UP;
144
        case MP_QSTR_RIGHT_DOWN:
145
        case MP_QSTR_RIGHT_MINUS:
146
            return PBIO_BUTTON_RIGHT_DOWN;
147
        default:
148
            return 0;
149
    }
150
}
151
#endif
152

153
/**
154
 * Common button pressed function for single button hubs.
155
 */
NEW
156
mp_obj_t pb_type_button_pressed_hub_single_button(mp_obj_t parent_obj) {
×
157
    pbio_button_flags_t flags = pbdrv_button_get_pressed();
×
158
    mp_obj_t buttons[] = { pb_type_button_new(MP_QSTR_CENTER) };
×
159

160
    #if MICROPY_PY_BUILTINS_SET
161
    return mp_obj_new_set(flags ? MP_ARRAY_SIZE(buttons) : 0, buttons);
×
162
    #else
163
    return mp_obj_new_tuple(flags ? MP_ARRAY_SIZE(buttons) : 0, buttons);
164
    #endif
165
}
166

167
#endif // PYBRICKS_PY_PARAMETERS_BUTTON
168

169
#endif // PYBRICKS_PY_PARAMETERS
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc