38
38
39
39
from adafruit_ble .attributes import Attribute
40
40
from adafruit_ble .characteristics import Characteristic , ComplexCharacteristic
41
- from adafruit_ble .characteristics .int import Uint8Characteristic
41
+ from adafruit_ble .characteristics .int import Uint8Characteristic , Uint16Characteristic
42
42
from adafruit_ble_adafruit .adafruit_service import AdafruitService
43
43
44
44
PixelValues = namedtuple ("PixelValues" , ("start" , "write_now" , "data" ),)
@@ -67,19 +67,19 @@ class _PixelPacket(ComplexCharacteristic):
67
67
data: raw array of data for all pixels, in proper color order for type of pixel
68
68
"""
69
69
70
+ MAX_LENGTH = 512
71
+
70
72
uuid = AdafruitService .adafruit_service_uuid (0x903 )
71
73
72
74
def __init__ (self ):
73
75
super ().__init__ (
74
76
properties = Characteristic .WRITE ,
75
77
read_perm = Attribute .NO_ACCESS ,
76
- max_length = 512 ,
78
+ max_length = self . MAX_LENGTH ,
77
79
)
78
80
79
81
def bind (self , service ):
80
82
"""Binds the characteristic to the given Service."""
81
- # Set Characteristic's max length, based on value from AddressablePixelService.
82
- # + 3 is for size of start and flags
83
83
bound_characteristic = super ().bind (service )
84
84
return _bleio .PacketBuffer (bound_characteristic , buffer_size = 1 )
85
85
@@ -98,31 +98,35 @@ class AddressablePixelService(AdafruitService):
98
98
uuid = AdafruitService .adafruit_service_uuid (0x902 ),
99
99
properties = (Characteristic .READ | Characteristic .WRITE ),
100
100
)
101
+
102
+ pixel_buffer_size = Uint16Characteristic (
103
+ uuid = AdafruitService .adafruit_service_uuid (0x904 ),
104
+ properties = (Characteristic .READ | Characteristic .WRITE ),
105
+ initial_value = _PixelPacket .MAX_LENGTH ,
106
+ )
107
+
101
108
"""
102
109
0 = WS2812 (NeoPixel), 800kHz
103
110
1 = SPI (APA102: DotStar)
104
111
"""
105
112
_pixel_packet = _PixelPacket ()
106
- """Pixel-setting data. max_length is supplied on binding. """
113
+ """Pixel-setting data."""
107
114
108
115
def __init__ (self , service = None ):
109
- self ._pixel_packet_buf = None
116
+ self ._pixel_packet_buf = bytearray ( _PixelPacket . MAX_LENGTH )
110
117
super ().__init__ (service = service )
111
118
112
119
@property
113
120
def values (self ):
114
121
"""Return a tuple (start, write_now, data) corresponding to the
115
122
different parts of ``_pixel_packet``.
116
123
"""
117
- if self ._pixel_packet_buf is None :
118
- self ._pixel_packet_buf = bytearray (
119
- self ._pixel_packet .packet_size # pylint: disable=no-member
120
- )
121
124
buf = self ._pixel_packet_buf
122
- if self ._pixel_packet .readinto (buf ) == 0 : # pylint: disable=no-member
125
+ num_read = self ._pixel_packet .readinto (buf ) # pylint: disable=no-member
126
+ if num_read == 0 :
123
127
# No new values available
124
128
return None
125
129
126
130
return PixelValues (
127
- struct .unpack_from ("<H" , buf )[0 ], bool (buf [2 ] & 0x1 ), buf [3 :],
131
+ struct .unpack_from ("<H" , buf )[0 ], bool (buf [2 ] & 0x1 ), buf [3 :num_read ],
128
132
)
0 commit comments