code: def from_body(cls, cemi):
          
          # TODO: check that length matches
          message = cls()
          message.code = cemi[0]
          offset = cemi[1]
  
          message.ctl1 = cemi[2 + offset]
          message.ctl2 = cemi[3 + offset]
  
          message.src_addr = cemi[4 + offset] * 256 + cemi[5 + offset]
          message.dst_addr = cemi[6 + offset] * 256 + cemi[7 + offset]
  
          message.mpdu_len = cemi[8 + offset]
  
          tpci_apci = cemi[9 + offset] * 256 + cemi[10 + offset]
          apci = tpci_apci & 0x3ff
  
          # for APCI codes see KNX Standard 03/03/07 Application layer
          # table Application Layer control field
          if apci & 0x080:
              # Group write
              message.cmd = CEMIMessage.CMD_GROUP_WRITE
          elif apci == 0:
              message.cmd = CEMIMessage.CMD_GROUP_READ
          elif apci & 0x40:
              message.cmd = CEMIMessage.CMD_GROUP_RESPONSE
          else:
              message.cmd = CEMIMessage.CMD_UNKNOWN
  
          apdu = cemi[10 + offset:]
          if len(apdu) != message.mpdu_len:
              raise KNXException(
                  "APDU LEN should be {} but is {}".format(
                      message.mpdu_len, len(apdu)))
  
          if len(apdu) == 1:
              message.data = [apci & 0x2f]
          else:
              message.data = cemi[11 + offset:]
  
          return message
docs: Create a new CEMIMessage initialized from the given CEMI data.