Closed f-bader closed 5 years ago
I can confirm this is working as my sensor is outside and it's winter.
I also confirm that this fixes this issue for single digit as well as negative values.
@f-bader you should update the comment in the commit regarding length of the string. For single digit temperature and single digit humidity this would be only 12 characters, and in case of temperatures at -10°C or below it would be 15 characters. For reference, I put the sensor in the freezer and got "0x54 0x3d 0x2d 0x31 0x31 0x2e 0x34 0x20 0x48 0x3d 0x37 0x30 0x2e 0x39 0x00" (T=-11.4 H=70.9).
@ratcashdev it would be great if this could be merged to support the sensor in temperatures below 10°C.
Thank you, will have a look.
@f-bader thanks for the submission. Could you possibly add also tests for this change?
Sure. Will take a look at the tests later today
@ratcashdev Please check my changes to test_parse.py
@f-bader tests are failing (run tox
)
> for dataitem in data.strip('\0').split(' '):
E TypeError: a bytes-like object is required, not 'str'
Keep in mind, that that _cache field during normal operations stores str
not bytes
- see handleNotification()
. In this way the test needs to be enhanced with data = bytes([0x54, 0x3d, 0x32, 0x35, 0x2e, 0x36, 0x20, 0x48, 0x3d, 0x32, 0x33, 0x2e, 0x36, 0x00]).decode("utf-8").strip(' \n\t')
for example.
Apparently, the previous implementation relied on the polymorphism of float()'s constructor, however, this is not the case with the new imlementation.
There are also some pylint errors.
Hi @ratcashdev
I tried to fix the tests but encounter an erro with python 2.7 This example code works fine with python 3.6 but not with 2.7
MI_TEMPERATURE = "temperature"
MI_HUMIDITY = "humidity"
MI_BATTERY = "battery"
data = bytes([0x54, 0x3d, 0x32, 0x35, 0x2e, 0x36, 0x20, 0x48, 0x3d, 0x32, 0x33, 0x2e, 0x36, 0x00]).decode("utf-8").strip(' \n\t')
res = dict()
for dataitem in data.strip('\0').split(' '):
dataparts = dataitem.split('=')
if dataparts[0] == 'T':
res[MI_TEMPERATURE] = float(dataparts[1])
elif dataparts[0] == 'H':
res[MI_HUMIDITY] = float(dataparts[1])
res
data.strip('\0').split(' ')
Python 2.7.15rc1
{} [u'[84,', u'61,', u'50,', u'53,', u'46,', u'54,', u'32,', u'72,', u'61,', u'50,', u'51,', u'46,', u'54,', u'0]'] Python 3.6.7 {'temperature': 25.6, 'humidity': 23.6} ['T=25.6', 'H=23.6']
If i replace the test data with data = str("T=25.6 H=23.6")
instead of the hex values it works just fine
Would that be fine for the unit tests as well? Will commit these changes if you give green light.
@f-bader It's important that we fill-in such data that are received from the device, actually, with the same type. During real operation handleNotification
is the method, that populsates the _cache field, and it is doing so using self._cache = raw_data.decode("utf-8").strip(' \n\t')
It would be nice if the tests could use the same sequence of processing instructions as handleNotification. Thus I propose to do the tests like this:
def test_parsing(self):
"""Does the Mi TEMP BT data parser works correctly?"""
poller = MiTempBtPoller(None, MockBackend)
data = bytes([0x54, 0x3d, 0x32, 0x35, 0x2e, 0x36, 0x20,
0x48, 0x3d, 0x32, 0x33, 0x2e, 0x36, 0x00]).decode("utf-8").strip(' \n\t')
poller._cache = data
poller._last_read = datetime.now()
self.assertEqual(poller._parse_data()[MI_TEMPERATURE], 25.6)
self.assertEqual(poller._parse_data()[MI_HUMIDITY], 23.6)
@ratcashdev I understand. But sadly this does not work with python 2.7 as described in my last post. So there seems to be a difference between the rawdata
and the used bytes
I check if I can find a solution that work for both Python versions.
@f-bader Python 2.7 is not supposed to work. See test/unit_tests/test_versioncheck.py Also since TOX does not throw errors for Python 2.7, it is ok.
@ratcashdev Changed the code to use bytearray
instead of bytes
and now tox is fine with the tests
bytes
is interpreted as string
which result in the error
Checked your latest commit. There are still some errors by tox.
tox -e py27,py35,py36,flake8
Original thanks to @rmiddlet Fix for issue #2 and #4
Tested on a raspberry pi