문제

I have Davis Vantagepro 2 weather station, and I'm using pyvantagepro (pip install pyvantagepro / GitHub ) to get current data out of the terminal device. It all works fine when outside temperature stays above 0 Fahrenheit, but unfortunately in Finland that's only like in July. When the temperature goes below 0 Fahrenheit, pyvantagepro returns TempOut value of something like 6549.098 (3620.61 °C).

Somebody somewhere suggested that the problem might be that the temperature is unsigned 16-bit integer, and that is why it flips around at that point.

I have no knowledge on how to fix that. I tried to change the LOOP_FORMAT on pyvantagepro's parser.py file from ('TempOut', 'H') to ('TempOut','I') in hopes for bigger values to fit in, but then nothing works anymore.

Any suggestions on how to get this working? I've no particular reason to use this and only this library, so feel free to suggest better libraries (better as in easy to use and confirmed to return temperatures below 0 Fahrenheit correctly).

I would've posted this on projects issue tracker, if there were one (404).

Thanks.

[Edit.]

It is fixed on current version, and now there's issue tracker.

도움이 되었습니까?

해결책

According to the python struct documentation the format specifiers H and I are both for unsigned data types. What is happening is that as the number goes below zero, unsigned variables wrap back around the number line and become very large positive numbers.

Most likely you could try using a lowercase h in the parser.py format string for a signed 16 bit int, however you could notice some strange values:

val = struct.pack('H', 100)
struct.unpack('h', val)[0]
# 100, YAY!

val = struct.pack('H', 32768)
struct.unpack('h', val)[0]
# -32768, UMMM?

Of course, this probably wouldn't be an issue in Finland, as temperature is likely to be below 3,276.7 farenheit on most days of the week - however its a bit ugly modifying the client library as it means you have to do this every time they provide updates.

You may be better off applying some basic fixes in your own code - test if the variable has wrapped and subtract the right amount. For instance have a look at the following:

struct.unpack('H', struct.pack('h', -1))[0]
# 65535

struct.unpack('H', struct.pack('h', -1))[0] - 65536
# -1

Of course we only want to subtract the 65,000 when we know our value has wrapped. As the client library appears to divide the received value by 10 to get a decimal point, you could do something like this:

if temp_value > 3276.7:
    temp_value -= 6553.5

The constant values here are based on the maximum value of an unsigned short (65535) and a signed short (half this value). In the long term it may also be worthwhile contacting the instrument maker to describe your problem and see what they suggest.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top