3838
3939from adafruit_ble .attributes import Attribute
4040from adafruit_ble .characteristics import Characteristic , ComplexCharacteristic
41- from adafruit_ble .characteristics .int import Uint8Characteristic
41+ from adafruit_ble .characteristics .int import Uint8Characteristic , Uint16Characteristic
4242from adafruit_ble_adafruit .adafruit_service import AdafruitService
4343
4444PixelValues = namedtuple ("PixelValues" , ("start" , "write_now" , "data" ),)
@@ -67,19 +67,19 @@ class _PixelPacket(ComplexCharacteristic):
6767 data: raw array of data for all pixels, in proper color order for type of pixel
6868 """
6969
70+ MAX_LENGTH = 512
71+
7072 uuid = AdafruitService .adafruit_service_uuid (0x903 )
7173
7274 def __init__ (self ):
7375 super ().__init__ (
7476 properties = Characteristic .WRITE ,
7577 read_perm = Attribute .NO_ACCESS ,
76- max_length = 512 ,
78+ max_length = self . MAX_LENGTH ,
7779 )
7880
7981 def bind (self , service ):
8082 """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
8383 bound_characteristic = super ().bind (service )
8484 return _bleio .PacketBuffer (bound_characteristic , buffer_size = 1 )
8585
@@ -98,31 +98,35 @@ class AddressablePixelService(AdafruitService):
9898 uuid = AdafruitService .adafruit_service_uuid (0x902 ),
9999 properties = (Characteristic .READ | Characteristic .WRITE ),
100100 )
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+
101108 """
102109 0 = WS2812 (NeoPixel), 800kHz
103110 1 = SPI (APA102: DotStar)
104111 """
105112 _pixel_packet = _PixelPacket ()
106- """Pixel-setting data. max_length is supplied on binding. """
113+ """Pixel-setting data."""
107114
108115 def __init__ (self , service = None ):
109- self ._pixel_packet_buf = None
116+ self ._pixel_packet_buf = bytearray ( _PixelPacket . MAX_LENGTH )
110117 super ().__init__ (service = service )
111118
112119 @property
113120 def values (self ):
114121 """Return a tuple (start, write_now, data) corresponding to the
115122 different parts of ``_pixel_packet``.
116123 """
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- )
121124 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 :
123127 # No new values available
124128 return None
125129
126130 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 ],
128132 )
0 commit comments