code: async def _encoder_data(self, data):
          
          # strip off sysex start and end
          data = data[1:-1]
          pin = data[0]
          if not self.hall_encoder:
              val = int((data[PrivateConstants.MSB] << 7) +
                        data[PrivateConstants.LSB])
              # set value so that it shows positive and negative values
              if val > 8192:
                  val -= 16384
              # if this value is different that is what is already in the
              # table store it and check for callback
              if val != self.digital_pins[pin].current_value:
                  self.digital_pins[pin].current_value = val
                  if self.digital_pins[pin].cb:
                      # self.digital_pins[pin].cb([pin, val])
                      if self.digital_pins[pin].cb_type:
                          await self.digital_pins[pin].cb(val)
                      else:
                          # self.digital_pins[pin].cb(data)
                          loop = self.loop
                          loop.call_soon(self.digital_pins[pin].cb, val)
          else:
              hall_data = [int((data[2] << 7) + data[1]), int((data[5] << 7) +
                                                              data[4])]
  
              if self.digital_pins[pin].cb_type:
                  await self.digital_pins[pin].cb(hall_data)
              else:
                  # self.digital_pins[pin].cb(data)
                  loop = self.loop
                  loop.call_soon(self.digital_pins[pin].cb, hall_data)
docs: This is a private message handler method.
          It handles encoder data messages.
  
          :param data: encoder data
  
          :returns: None - but update is saved in the digital pins structure