bricknil.sensor.peripheral¶
Base class for all sensors and motors
Classes¶
| Peripheral(name[, port, capabilities]) | Abstract base class for any Lego Boost/PoweredUp/WeDo peripherals | 
Members¶
- 
class bricknil.sensor.peripheral.Peripheral(name, port=None, capabilities=[])[source]¶
- Bases: - bricknil.process.Process- Abstract base class for any Lego Boost/PoweredUp/WeDo peripherals - A LEGO sensor can provide either a single sensing capability, or a combined mode where it returns multiple sensing values. All the details can be found in the official protocol description. - Single capability - This is the easiest to handle:
- Send a 0x41 Port Input Format Setup command to put the sensor port into the respective mode and activate updates
- Read back the 0x45 Port Value(Single) messages with updates from the sensor on the respective mode
 
 
- Multiple capabilities - This is more complicated because we need to put the sensor port into CombinedMode
- Send a [0x42, port, 0x02] message to lock the port
- Send multiple 0x41 messages to activate each capability/mode we want updates from
- Send a [0x42, port, 0x01, ..] message with the following bytes:
- 0x00 = Row entry 0 in the supported combination mode table
- (hard-coded for simplicity here because LEGO seems to only use this entry most of the time)
 
- For each mode/capability, send a byte like the following:
- Upper 4-bits is mode number
- Lower 4-bits is the dataset number
- For example, for getting RGB values, it’s mode 6, and we want all three datasets
- (for each color), so we’d add three bytes [0x60, 0x61, 0x62]. If you just wanted the Red value, you just append [0x60]
 
 
 
 
 
- Send a [0x42, port, 0x03] message to unlock the port
- Now, when the sensor sends back values, it uses 0x46 messages with the following byte sequence:
- Port id
- 16-bit entry where the true bits mark which mode has values included in this message
- (So 0x00 0x05 means values from Modes 2 and 0)
 
- Then the set of values from the sensor, which are ordered by Mode number
- (so the sensor reading from mode 0 would come before the reading from mode 2)
 
- Each set of values includes however many bytes are needed to represent each dataset
- (for example, up to 3 for RGB colors), and the byte-width of each value (4 bytes for a 32-bit int)
 
 
 
 
 
 - Parameters: - capabilities – can be input in the following formats (where the number in the tuple can be a threshold to trigger updates) - [‘sense_color’, ‘sense_distannce’]
- [capability.sense_color, capability.sense_distance]
- [(‘sense_color’, 1), (‘sense_distance’, 2)]
 
- name (str) – Human readable name
- port (int) – Port to connect to (otherwise will connect to first matching peripheral with defined sensor_id)
 - 
message_handler¶
- Outgoing message queue to BLEventQ that’s set by the Hub when an attach message is seen - Type: - func 
 - 
capabilites¶
- Support capabilities - Type: - list [ capability ] 
 - 
thresholds¶
- Integer list of thresholds for updates for each of the sensing capabilities - Type: - list [ int ] 
 - 
class Dataset(n, w, min, max)¶
- Bases: - tuple- Create new instance of Dataset(n, w, min, max) - 
max¶
- Alias for field number 3 
 - 
min¶
- Alias for field number 2 
 - 
n¶
- Alias for field number 0 
 - 
w¶
- Alias for field number 1 
 
- 
 - 
activate_updates()[source]¶
- Send a message to the sensor to activate updates - Called via an ‘attach’ message from - bricknil.messages.Message.parse_attached_io()that triggers this call from- bricknil.hub.Hub.peripheral_message_loop()- See class description for explanation on how Combined Mode updates are done. - Returns: - None 
 - 
set_output(mode, value)[source]¶
- Don’t change this unless you’re changing the way you do a Port Output command - Outputs the following sequence to the sensor
- 0x00 = hub id from common header
- 0x81 = Port Output Command
- port
- 0x11 = Upper nibble (0=buffer, 1=immediate execution), Lower nibble (0=No ack, 1=command feedback)
- 0x51 = WriteDirectModeData
- mode
- value(s)
 
 
 - 
update_value(msg_bytes)[source]¶
- Message from message_dispatch will trigger Hub to call this to update a value from a sensor incoming message Depending on the number of capabilities enabled, we end up with different processing: - If zero, then just set the self.value field to the raw message. - If one, then:
- Parse the single sensor message which may have multiple data items (like an RGB color value)
- self.value dict entry for this capability becomes a list of these values
 
- If multiple, then:
- Parse multiple sensor messages (could be any combination of the enabled modes)
- Set each dict entry to self.value to either a list of multiple values or a single value