ustruct.unpack() - decodage de valeurs binaires

Je me frotte au senseur AM2315 sous MicroPython pour ESP8266... et me voila noyé dans le décodage de valeurs binaire pour extraire le CRC16 de la réponse.
Senseur Humidité - Température AM2315 disponible chez MCHobby

Pour l'instant, le buffer (mémoire tampon) de réponse ressemble à ceci:

>>> a.rbuf
bytearray(b'\x03\x04\x01\xb7\x00\xf7\x01\xb4')

Le CRC16 (donc deux octets) est en fin de trame, donc les octets \x01\xb4

Nous pouvons facilement obtenir la liste des valeurs buffer avec un unpack comme celui-ci:
>>> ustruct.unpack('BBBBBBBB', a.rbuf )
(3, 4, 1, 183, 0, 247, 1, 180)

Le CRC16 est codé sur \0x1\xb4 avec \0x1 en poids faible et 0x4b en poids fort.

Si on regarde la représentation binaire des deux derniers octets est:
>>> "{0:b}".format(a.rbuf[6])
'1'
>>> "{0:b}".format(a.rbuf[7])
'10110100'


Le CRC16 attendu (par expérience) est la valeur 46081 , ce qui correspond à sa représentation binaire suivante. Nous pouvons constater que la représentation binaire du dernier octet du buffer (\xb4) est placé en poids fort... et la représentation de l'avant dernier octet du buffer (\x01) arrive en poids faible.

>>> "{0:b}".format(v)
'1011010000000001'

Voici comment décoder la valeur avec ustruct.unpack(), plus d'info ici et sur Python Struct.

Commençons par isoler les deux derniers octets:

>>> a.rbuf[-2:]
bytearray(b'\x01\xb4')

Puis calculons la valeur du mot:

>>> ustruct.unpack( '<H', a.rbuf[-2:] )
(46081,)

Un petit cas pratique c'est toujours utile :-)