# [ubuntu-uk] Reverse engineering data files

Thu Nov 27 13:49:54 UTC 2014

```On Thu, 27 Nov 2014, Gareth France wrote:
> I really don't understand what you have done here.
> >>>> > >>F3 01 90 B7  - 42.79 - 0x90b7 & 0x7fff => 0x10b7 => 4279 decimal
> >>>> > >>F3 01 97 78  - 60.08 - 0x9778 & 0x7fff => 0x1778 => 6008 decimal

The two bytes we're interested in (0x90b7) together give us 16 bits of
information.  This is split into two, 1-bit for one value (true or
false) and 15-bits for a measurement value (zero to 32k).

0x90b7
1001000010110111 (binary)

When we split it, the two parts are:

1 and 001000010110111

We can pass these to Python to convert from binary to decimal; the
'0b' prefix means binary, just like '0x' means hexadecimal:

python -c 'print 0b1, 0b001000010110111'
1 4279

The first value is actually a boolean (True/False) and is inverted,
and the second is multipled by 100:

python -c 'print bool(not 0b1), 0.01*0b001000010110111'
False 42.79

We don't need to go to the binary representation at all, we can split
the field using bitwise arithmatic AND (&) and right shift (>>) :

https://en.wikipedia.org/wiki/Bitwise_operation#AND
https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift

python -c 'print bool(not 0x90b7 >> 15), 0.01 * (0x90b7 & 0x7fff)'
False 42.79

We can test this another result too:

python -c 'print bool(not 0x9778 >> 15), 0.01 * (0x9778 & 0x7fff)'
False 60.08

python -c 'print bool(not 0x48db >> 15), 0.01 * (0x48db & 0x7fff)'
True 186.51

In this case, this is above >99.99, which the new meter shows as
'99.99' so we need to cap it with the minimum function:

python -c 'print bool(~0x48db>>15),min(99.99,0.01*(0x48db&0x7fff))'
True 99.99

and just to re-check with the others:

python -c 'print bool(not 0x9778>>15),min(99.99,0.01*(0x9778&0x7fff))'
False 60.08

-Paul

```