# [ubuntu-uk] Reverse engineering data files

Gareth France gareth.france at cliftonts.co.uk
Thu Nov 27 22:45:57 UTC 2014

```I'm still not getting predictable results with this. The 42.79 works
great but the 99.99 results don't co-operate. Also the hex seems
different for each one which is strange.

F3 01 48 79
F3 01 48 D8
F3 01 48 DB
F3 01 48 D6
F3 01 48 D9
F3 01 48 C0
F3 01 48 49
F3 01 48 9C
F3 01 48 C6
F3 01 48 D3
F3 01 48 6E

Some of these were duplicated but they are all results that came up as
99.99. I've played round with all sorts of combinations but can't come
up with anything that works. Any ideas appreciated.

On 27/11/14 13:49, Paul Sladen wrote:
> 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
>
>
>
>

```