tony-fav / tasmota-blerry

GNU General Public License v3.0
96 stars 29 forks source link

Initial support for GVH5074 #21

Closed cornking03 closed 2 years ago

cornking03 commented 2 years ago

Values reported over MQTT all match expected values. Several features were added following examples from existing drivers, but not tested such as HA discovery, via_pubs, and publish attributes.

tony-fav commented 2 years ago

Looks good.

Have you tested with a negative temp on your device? By my research on this device, the negative is stored via 2s complement, not the same way it is stored in the GVH5075 (as you've done here just with 2 bytes rather than 3).

This code snippet demos the difference between the 2 methods

import string

def twos_complement(n, w)
  if n & (1 << (w - 1))
    n = n - (1 << w)
  end
  return n
end

def gvh5075_way(n, w)
  if n & (1 << (w - 1))
    n = (1 << (w - 1)) - n
  end
  return n
end

for x:0x7FF0..0x800F
  print(string.format('0x%X', x), gvh5075_way(x, 16), twos_complement(x, 16))
end

with output

0x7FF0 32752 32752
0x7FF1 32753 32753
0x7FF2 32754 32754
0x7FF3 32755 32755
0x7FF4 32756 32756
0x7FF5 32757 32757
0x7FF6 32758 32758
0x7FF7 32759 32759
0x7FF8 32760 32760
0x7FF9 32761 32761
0x7FFA 32762 32762
0x7FFB 32763 32763
0x7FFC 32764 32764
0x7FFD 32765 32765
0x7FFE 32766 32766
0x7FFF 32767 32767
0x8000 0 -32768
0x8001 -1 -32767
0x8002 -2 -32766
0x8003 -3 -32765
0x8004 -4 -32764
0x8005 -5 -32763
0x8006 -6 -32762
0x8007 -7 -32761
0x8008 -8 -32760
0x8009 -9 -32759
0x800A -10 -32758
0x800B -11 -32757
0x800C -12 -32756
0x800D -13 -32755
0x800E -14 -32754
0x800F -15 -32753
cornking03 commented 2 years ago

I did throw my GVH5074 in the freezer and was receiving correct negative readings from it (I was also pleasantly surprised with the signal strength for it being inside a metal box). I am not very familiar with bitwise operations and just learned about two's complement today (thanks)! I added my method to yours above...

...

def GVH5074_initial_way(n)  
  if n <= 0x7FFF
    return n 
  end
  return (-(0xFFFF - n))
end

for x:0x7FF0..0x800F
  print(string.format('0x%X', x), gvh5075_way(x, 16), twos_complement(x, 16), GVH5074_initial_way(x))
end

Output:

0x7FF1 32753 32753 32753
0x7FF2 32754 32754 32754
0x7FF3 32755 32755 32755
0x7FF4 32756 32756 32756
0x7FF5 32757 32757 32757
0x7FF6 32758 32758 32758
0x7FF7 32759 32759 32759
0x7FF8 32760 32760 32760
0x7FF9 32761 32761 32761
0x7FFA 32762 32762 32762
0x7FFB 32763 32763 32763
0x7FFC 32764 32764 32764
0x7FFD 32765 32765 32765
0x7FFE 32766 32766 32766
0x7FFF 32767 32767 32767
0x8000 0 -32768 -32767
0x8001 -1 -32767 -32766
0x8002 -2 -32766 -32765
0x8003 -3 -32765 -32764
0x8004 -4 -32764 -32763
0x8005 -5 -32763 -32762
0x8006 -6 -32762 -32761
0x8007 -7 -32761 -32760
0x8008 -8 -32760 -32759
0x8009 -9 -32759 -32758
0x800A -10 -32758 -32757
0x800B -11 -32757 -32756
0x800C -12 -32756 -32755
0x800D -13 -32755 -32754
0x800E -14 -32754 -32753
0x800F -15 -32753 -32752

I'm not sure if I just got lucky with my method or if the math actually checks out, but I can update mine to use the two's complement.

tony-fav commented 2 years ago

Looks like you're super close to a twos_complement but missing the shift by 1 (see here). The function I used is basically this. However, I'm thinking berry uses Two's Complement when it extracts data with the geti method. So, we may be able to get rid of the if statement with just changing var temp = adv_data.get(3,2) to var temp = adv_data.geti(3,2) Give it a try and let me know!

tony-fav commented 2 years ago

I see the commit, but I just want to confirm before I merge that the change gets you good temperature values (positive and negative).

cornking03 commented 2 years ago

Forgot to actually submit my comment after that commit yesterday. I did confirm that the change returns correct positive and negative values.

image