Notes on LEGO wireless BLE protocol

PoweredUp and Boost Hub

Vision sensor information

1: {'combinable': True,
    'id': 37,
    'input': True,
    'mode_combinations': [[0, 1, 2, 3, 6]],
    'modes': {0: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input': True,
                  'input_mapping': ['Discrete',
                                    'Supports Functional Mapping 2.0}',
                                    'Supports NULL'],
                  'name': 'COLOR',
                  'output_mapping': [],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 10.0),
                  'si_range': (0.0, 10.0),
                  'symbol': 'IDX'},
              1: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input': True,
                  'input_mapping': ['Absolute',
                                    'Supports Functional Mapping 2.0}'],
                  'name': 'PROX',
                  'output_mapping': [],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 10.0),
                  'si_range': (0.0, 10.0),
                  'symbol': 'DIS'},
              2: {'dataset_decimals': 0,
                  'dataset_total_figures': 4,
                  'dataset_type': '32b',
                  'datasets': 1,
                  'input': True,
                  'input_mapping': ['Relative'],
                  'name': 'COUNT',
                  'output_mapping': [],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 100.0),
                  'si_range': (0.0, 100.0),
                  'symbol': 'CNT'},
              3: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input': True,
                  'input_mapping': ['Absolute'],
                  'name': 'REFLT',
                  'output_mapping': [],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 100.0),
                  'si_range': (0.0, 100.0),
                  'symbol': 'PCT'},
              4: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input': True,
                  'input_mapping': ['Absolute'],
                  'name': 'AMBI',
                  'output_mapping': [],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 100.0),
                  'si_range': (0.0, 100.0),
                  'symbol': 'PCT'},
              5: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input_mapping': [],
                  'name': 'COL O',
                  'output': True,
                  'output_mapping': ['Discrete'],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 10.0),
                  'si_range': (0.0, 10.0),
                  'symbol': 'IDX'},
              6: {'dataset_decimals': 0,
                  'dataset_total_figures': 5,
                  'dataset_type': '16b',
                  'datasets': 3,
                  'input': True,
                  'input_mapping': ['Absolute'],
                  'name': 'RGB I',
                  'output_mapping': [],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 1023.0),
                  'si_range': (0.0, 1023.0),
                  'symbol': 'RAW'},
              7: {'dataset_decimals': 0,
                  'dataset_total_figures': 5,
                  'dataset_type': '16b',
                  'datasets': 1,
                  'input_mapping': [],
                  'name': 'IR Tx',
                  'output': True,
                  'output_mapping': ['Discrete'],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 65535.0),
                  'si_range': (0.0, 65535.0),
                  'symbol': 'N/A'},
              9: {'dataset_decimals': 0,
                  'dataset_total_figures': 5,
                  'dataset_type': '16b',
                  'datasets': 2,
                  'input': True,
                  'input_mapping': ['Absolute'],
                  'name': 'DEBUG',
                  'output_mapping': [],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 1023.0),
                  'si_range': (0.0, 10.0),
                  'symbol': 'N/A'},
              10: {'dataset_decimals': 0,
                   'dataset_total_figures': 5,
                   'dataset_type': '16b',
                   'datasets': 8,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'CALIB',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 65535.0),
                   'si_range': (0.0, 65535.0),
                   'symbol': 'N/A'}},
    'name': 'Vision Sensor',
    'output': True},

Tilt sensor information

58: {'combinable': True,
     'id': 40,
     'input': True,
     'mode_combinations': [[0, 1, 2, 3, 4]],
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 2,
                   'input': True,
                   'name': 'ANGLE'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'TILT'},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'ORINT'},
               3: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '32b',
                   'datasets': 1,
                   'input': True,
                   'name': 'IMPCT'},
               4: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input': True,
                   'name': 'ACCEL'},
               5: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'OR_CF'},
               6: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 2,
                   'input': True,
                   'name': 'IM_CF'},
               7: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input': True,
                   'name': 'CALIB'}},
     'name': 'Internal Tilt'},

Internal Motor information

Two motors on ports 55 and 56 on the Boost Hub

55: {'combinable': True,
     'id': 39,
     'input': True,
     'mode_combinations': [[1, 2]],
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'name': 'POWER',
                   'output': True},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'SPEED',
                   'output': True},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '32b',
                   'datasets': 1,
                   'input': True,
                   'name': 'POS',
                   'output': True}},
     'name': 'Internal Motor with Tacho',
     'output': True,
     'synchronizable': True},
56: {'combinable': True,
     'id': 39,
     'input': True,
     'mode_combinations': [[1, 2]],
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'name': 'POWER',
                   'output': True},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'SPEED',
                   'output': True},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '32b',
                   'datasets': 1,
                   'input': True,
                   'name': 'POS',
                   'output': True}},
     'name': 'Internal Motor with Tacho',
     'output': True,
     'synchronizable': True},

External Motor information

{1: {'combinable': True,
     'id': 38,
     'input': True,
     'mode_combinations': [[1, 2]],
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'name': 'POWER',
                   'output': True},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'SPEED'},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 6,
                   'dataset_type': '32b',
                   'datasets': 1,
                   'input': True,
                   'name': 'POS'}},
     'name': 'External Motor with Tacho',
     'output': True},

Current/Voltage information

Ports 59 and 60 on the Boost hub and Pup hub

59: {'id': 21,
     'input': True,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '16b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'CUR L',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 4095.0),
                   'si_range': (0.0, 2444.0),
                   'symbol': 'mA'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '16b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'CUR S',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 4095.0),
                   'si_range': (0.0, 2444.0),
                   'symbol': 'mA'}},
     'name': 'Current'},
60: {'id': 20,
     'input': True,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '16b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'VLT L',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 3893.0),
                   'si_range': (0.0, 9600.0),
                   'symbol': 'mV'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '16b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'VLT S',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 3893.0),
                   'si_range': (0.0, 9600.0),
                   'symbol': 'mV'}},
     'name': 'Voltage'},

Hub LED information

50: {'id': 23,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input_mapping': [],
                   'name': 'COL O',
                   'output': True,
                   'output_mapping': ['Discrete',
                                      'Supports Functional Mapping 2.0}'],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 10.0),
                   'si_range': (0.0, 10.0),
                   'symbol': ''},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input_mapping': [],
                   'name': 'RGB O',
                   'output': True,
                   'output_mapping': ['Absolute'],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 255.0),
                   'si_range': (0.0, 255.0),
                   'symbol': ''}},
     'name': 'RGB Light',
     'output': True},

Remote buttons

Two buttons on port 0 and 1

  • Port 0 - Left side
  • Port 1 - Right side
Modes and returned values:
# rckey
  • 0 = Nothing pressed
  • 1 = ‘+’ button pushed
  • 255 = ‘-‘ button pushed
  • 127 = ‘red’ button pushed

# keyr same # keya same

# keyd -
  • 0 = Nothing pressed
  • 1 = ‘+’
  • 2 = red
  • 4 = ‘-‘
# keysd bitmask (can tell when multiple buttons are being pressed)
  • [0,0,0] = Nothing pressed
  • [1,0,0] = ‘+’
  • [0,1,0] = red
  • [0,0,1] = ‘-‘
{0: {'id': 55,
     'input': True,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 2,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'RCKEY'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 2,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'KEYA '},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 2,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'KEYR '},
               3: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'KEYD '},
               4: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input': True,
                   'name': 'KEYSD'}},
     'name': 'Remote Button'},
 1: {'id': 55,
     'input': True,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 2,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'RCKEY'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 2,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'KEYA '},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 2,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'KEYR '},
               3: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'name': 'KEYD '},
               4: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input': True,
                   'name': 'KEYSD'}},
     'name': 'Remote Button'},

Train Motor

0: {'id': 2,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input_mapping': [],
                   'name': 'LPF2-TRAIN',
                   'output': True,
                   'output_mapping': ['Relative', 'Absolute'],
                   'pct_range': (-100.0, 100.0),
                   'raw_range': (-100.0, 100.0),
                   'si_range': (-100.0, 100.0),
                   'symbol': ''}},
     'name': 'System Train Motor',
     'output': True},

WeDO

External Tilt sensor information

1: {'combinable': 0,
     'id': 34,
     'input': 2,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 2,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'LPF2-ANGLE',
                   'output_mapping': [],
                   'pct_range': (-100.0, 100.0),
                   'raw_range': (-45.0, 45.0),
                   'si_range': (-45.0, 45.0),
                   'symbol': 'DEG'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 2,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Discrete'],
                   'name': 'LPF2-TILT',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 10.0),
                   'si_range': (0.0, 10.0),
                   'symbol': 'DIR'},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'LPF2-CRASH',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 100.0),
                   'si_range': (0.0, 100.0),
                   'symbol': 'CNT'},
               3: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'LPF2-CAL',
                   'output_mapping': [],
                   'pct_range': (-100.0, 100.0),
                   'raw_range': (-45.0, 45.0),
                   'si_range': (-45.0, 45.0),
                   'symbol': 'CAL'}},
     'name': 'External Tilt Sensor',
     'output': 0,
     'synchronizable': 0},

External Motion sensor information

1: {'combinable': 0,
     'id': 35,
     'input': 2,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'LPF2-DETECT',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 10.0),
                   'si_range': (0.0, 10.0),
                   'symbol': ''},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '32b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'LPF2-COUNT',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 100.0),
                   'si_range': (0.0, 100.0),
                   'symbol': 'CNT'},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '16b',
                   'datasets': 3,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'LPF2-CAL',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 1023.0),
                   'si_range': (0.0, 1023.0),
                   'symbol': 'RAW'}},
     'name': 'Motion Sensor',
     'output': 0,
     'synchronizable': 0},

External Wedo Motor information

1: {'combinable': 0,
     'id': 1,
     'input': 0,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input_mapping': [],
                   'name': 'LPF2-MMOTOR',
                   'output': True,
                   'output_mapping': ['Absolute'],
                   'pct_range': (-100.0, 100.0),
                   'raw_range': (-100.0, 100.0),
                   'si_range': (-100.0, 100.0),
                   'symbol': ''}},
     'name': 'Motor',
     'output': 1,
     'synchronizable': 0},

Duplo

Duplo Train Motor

{0: {'id': 41,
     'input': True,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input_mapping': [],
                   'name': 'T MOT',
                   'output': True,
                   'output_mapping': ['Absolute',
                                      'Supports Functional Mapping 2.0}'],
                   'pct_range': (-100.0, 100.0),
                   'raw_range': (-100.0, 100.0),
                   'si_range': (-100.0, 100.0),
                   'symbol': 'pwr'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '32b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Relative'],
                   'name': 'ONSEC',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 1.0),
                   'si_range': (0.0, 1.0),
                   'symbol': 'sec'}},
     'name': 'Duplo Train Motor',
     'output': True},

Duplo Train Speaker

1: {'id': 42,
    'modes': {0: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input_mapping': [],
                  'name': 'TONE',
                  'output': True,
                  'output_mapping': ['Discrete'],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 10.0),
                  'si_range': (0.0, 10.0),
                  'symbol': 'idx'},
              1: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input_mapping': [],
                  'name': 'SOUND',
                  'output': True,
                  'output_mapping': ['Discrete',
                                     'Supports Functional Mapping 2.0}'],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 10.0),
                  'si_range': (0.0, 10.0),
                  'symbol': 'idx'},
              2: {'dataset_decimals': 0,
                  'dataset_total_figures': 3,
                  'dataset_type': '8b',
                  'datasets': 1,
                  'input_mapping': [],
                  'name': 'UI SND',
                  'output': True,
                  'output_mapping': ['Discrete'],
                  'pct_range': (0.0, 100.0),
                  'raw_range': (0.0, 10.0),
                  'si_range': (0.0, 10.0),
                  'symbol': 'idx'}},
    'name': 'Duplo Train Speaker',
    'output': True},

Duplo Train Color

18: {'combinable': True,
     'id': 43,
     'input': True,
     'mode_combinations': [[0, 1, 2, 3]],
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Discrete', 'Supports NULL'],
                   'name': 'COLOR',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 10.0),
                   'si_range': (0.0, 10.0),
                   'symbol': 'idx'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Discrete',
                                     'Supports Functional Mapping 2.0}',
                                     'Supports NULL'],
                   'name': 'C TAG',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 10.0),
                   'si_range': (0.0, 10.0),
                   'symbol': 'idx'},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'REFLT',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 100.0),
                   'si_range': (0.0, 100.0),
                   'symbol': 'raw'},
               3: {'dataset_decimals': 0,
                   'dataset_total_figures': 5,
                   'dataset_type': '16b',
                   'datasets': 3,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'RGB I',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 1023.0),
                   'si_range': (0.0, 1023.0),
                   'symbol': 'raw'},
               4: {'dataset_decimals': 0,
                   'dataset_total_figures': 5,
                   'dataset_type': '16b',
                   'datasets': 3,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'CALIB',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 8000.0),
                   'si_range': (0.0, 8000.0),
                   'symbol': ''}},
     'name': 'Duplo Train Color'},

Duplo Train Speedometer

19: {'combinable': True,
     'id': 44,
     'input': True,
     'mode_combinations': [[0, 1]],
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 5,
                   'dataset_type': '16b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute',
                                     'Supports Functional Mapping 2.0}'],
                   'name': 'SPEED',
                   'output_mapping': [],
                   'pct_range': (-100.0, 100.0),
                   'raw_range': (-300.0, 300.0),
                   'si_range': (-10.0, 10.0),
                   'symbol': 'spd'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '32b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Relative'],
                   'name': 'COUNT',
                   'output_mapping': [],
                   'pct_range': (-100.0, 100.0),
                   'raw_range': (8.0, 8.0),
                   'si_range': (360.0, 360.0),
                   'symbol': 'cnt'},
               2: {'dataset_decimals': 0,
                   'dataset_total_figures': 5,
                   'dataset_type': '16b',
                   'datasets': 4,
                   'input': True,
                   'input_mapping': ['Relative'],
                   'name': 'CALIB',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 4096.0),
                   'si_range': (0.0, 4096.0),
                   'symbol': 'n/a'}},
     'name': 'Duplo Train Speedometer'},

Duplo Train RGB Light

17: {'id': 23,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 1,
                   'dataset_type': '8b',
                   'datasets': 1,
                   'input_mapping': [],
                   'name': 'COL O',
                   'output': True,
                   'output_mapping': ['Discrete',
                                      'Supports Functional Mapping 2.0}'],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 10.0),
                   'si_range': (0.0, 10.0),
                   'symbol': ''},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 3,
                   'dataset_type': '8b',
                   'datasets': 3,
                   'input_mapping': [],
                   'name': 'RGB O',
                   'output': True,
                   'output_mapping': ['Absolute'],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 255.0),
                   'si_range': (0.0, 255.0),
                   'symbol': ''}},
     'name': 'RGB Light',
     'output': True},

Duplo Train Voltage

20: {'id': 20,
     'input': True,
     'modes': {0: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '16b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'VLT L',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 3047.0),
                   'si_range': (0.0, 6400.0),
                   'symbol': 'mV'},
               1: {'dataset_decimals': 0,
                   'dataset_total_figures': 4,
                   'dataset_type': '16b',
                   'datasets': 1,
                   'input': True,
                   'input_mapping': ['Absolute'],
                   'name': 'VLT S',
                   'output_mapping': [],
                   'pct_range': (0.0, 100.0),
                   'raw_range': (0.0, 3047.0),
                   'si_range': (0.0, 6400.0),
                   'symbol': 'mV'}},
     'name': 'Voltage'},