Help on driver development

143 views
Skip to first unread message

Anders Fosgerau

unread,
Feb 2, 2022, 5:24:29 PM2/2/22
to weewx-user

I recently replaced my weather station with a TFA Dostmann Weatherhub station only to discover that the driver situation was suboptimal. The tfrec driver was an option, but apparently the implementation of the weatherhub packet data format was different/not supported/incompatible.

But there is a nice API which provides access to the latest measurements (https://mobile-alerts.eu/info/public_server_api_documentation.pdf). So I started writing a driver inspired by the ambientweather-api driver by Karl Moos.

As only the latest measurements are available in the API, my idea was to let the driver only generate LOOP packets, going through a loop of polling the API, processing, generating LOOP packets, sleeping and starting all over. Weewx should then generate the necessary archive packets.

The API allows polling data once per minute, but sensors are updated less frequently. My first implementation generated partial LOOP packets only containing sensors updated since last polling. It turned out to be less optimal as the software archive record generation apparently don’t like “averaging” over a sequence of partial LOOP packets, so NONE values for temperatures, barometer stc end up in the archive database:

MariaDB [weewx]> select dateTime,barometer,inTemp,outTemp,rain,extraTemp1 from archive order by dateTime desc limit 20;

+------------+--------------------+--------------------+---------------------+------+-------------------+

| dateTime   | barometer          | inTemp             | outTemp             | rain | extraTemp1        |

+------------+--------------------+--------------------+---------------------+------+-------------------+

| 1643837100 | 1014.2999999999998 | 21.899999999999995 |                  -1 | NULL |               5.5 |

| 1643836800 |             1014.3 |               21.9 |                -1.2 | NULL |               5.6 |

| 1643836200 | 1014.2000000000002 | 21.899999999999995 | -1.3999999999999997 | NULL | 5.599999999999999 |

| 1643835900 | 1014.2000000000002 | 21.899999999999995 | -1.6000000000000003 | NULL | 5.599999999999999 |

| 1643835600 |             1014.2 |               21.9 |                -1.6 | NULL |               5.6 |

| 1643835000 |             1014.2 |               21.9 |                NULL | NULL |              NULL |

| 1643834700 |             1014.1 |               21.9 |                -1.7 | NULL |               5.7 |

| 1643834400 |             1014.2 |               21.9 |                -1.8 | NULL |               5.8 |

| 1643834100 |             1014.1 |                 22 |                -1.8 | NULL |               5.8 |

| 1643833800 |               NULL |               NULL |                -1.8 | NULL |               5.8 |

| 1643833500 |             1014.2 |                 22 |                -1.8 | NULL |               5.8 |

| 1643833200 |             1014.2 |               21.9 |                -1.9 | NULL |               5.9 |

| 1643832900 |             1014.1 |                 22 |                NULL | NULL |              NULL |  

Question 1: What would be the most appropriate solution: To let the LOOP packets also include “older”, non-updated observations already submitted in a previous LOOP packet? Or to lower the period of LOOP packets generation to increase the probability of all sensors have reported back between loop packets?

-----------------

I’ve been unable to make the windspeed and windgust observations work. When I enable them I get this error from weewx:

Feb  2 22:14:56 hjernen weewx[4163320] INFO weewx.engine: Starting main packet loop.

Feb  2 22:14:56 hjernen weewx[4163320] DEBUG user.mobilealerts: calling: genLoopPackets

Feb  2 22:14:56 hjernen weewx[4163320] DEBUG urllib3.connectionpool: Starting new HTTPS connection (1): www.data199.com:443

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG urllib3.connectionpool: https://www.data199.com:443 "POST /api/pv1/device/lastmeasurement HTTP/1.1" 200 398

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Init API call returned

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: API response passed initial tests

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found 030A7AB85B1D last seen on 2022-02-02 22:11:43

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: extraTemp1 = 5.6

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: extraHumid1 = 68.0

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found 183391FAA6CA last seen on 2022-02-02 22:12:12

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: inTemp = 21.9

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: inHumidity = 48.0

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: barometer = 1014.1

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found 0B70310CE043 last seen on 2022-02-02 22:13:04

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: windSpeed = 0.1

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: windDir = 10

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found 030A731F05FD last seen on 2022-02-02 22:11:18

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: outTemp = -1.2

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found sensor value: outHumidity = 95.0

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG user.mobilealerts: Found 0823ED826F59 last seen on 2022-02-02 21:46:52

Feb  2 22:14:57 hjernen weewx[4163320] INFO user.mobilealerts: Yielding this packet to weewx: {'dateTime': 1643836497, 'usUnits': 17, 'extraTemp1': 5.6, 'extraHumid1': 68.0, 'inTemp': 21.9, 'inHumidity': 48.0, 'barometer': 1014.1, 'windSpeed': '0.1', 'windDir': 225.0, 'outTemp': -1.2, 'outHumidity': 95.0}

Feb  2 22:14:57 hjernen weewx[4163320] INFO weewx.engine: Main loop exiting. Shutting engine down.

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG weewx.restx: Shut down MQTT thread.

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG weewx.restx: Shut down Wunderground-PWS thread.

Feb  2 22:14:57 hjernen weewx[4163320] DEBUG weewx.restx: Shut down StationRegistry thread.

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__: Caught unrecoverable exception:

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****  can't multiply sequence by non-int of type 'float'

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****  Traceback (most recent call last):

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewxd", line 157, in main

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      engine.run()

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewx/engine.py", line 210, in run

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      self.dispatchEvent(weewx.Event(weewx.NEW_LOOP_PACKET, packet=packet))

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewx/engine.py", line 245, in dispatchEvent

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      callback(event)

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewx/engine.py", line 363, in new_loop_packet

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      converted_packet = self.converter.convertDict(event.packet)

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewx/units.py", line 1040, in convertDict

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      target_dict[obs_type] = self.convert(as_value_tuple(obs_dict, obs_type))[0]

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewx/units.py", line 1007, in convert

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      new_val_t = convert(val_t, new_unit_type)

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewx/units.py", line 1563, in convert

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      new_val = conversion_func(val_t[0]) if val_t[0] is not None else None

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****    File "/usr/share/weewx/weewx/units.py", line 417, in <lambda>

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****      'km_per_hour'      : lambda x : x * 3.6},

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****  TypeError: can't multiply sequence by non-int of type 'float'

Feb  2 22:14:57 hjernen weewx[4163320] CRITICAL __main__:     ****  Exiting.

 

Question 2: What am I doing wrong?

 

Thank you for any assistance,

Anders

 

Tom Keffer

unread,
Feb 2, 2022, 6:02:03 PM2/2/22
to weewx-user
Q1: It looks like you have an archive interval of 5 minutes. I suspect the problem is that some variables are not getting updated that often. When it comes time to extract an archive value there are no valid measurements, so null is returned. 

Solution? Yes, you could use old values, although this violates two rules of driver development:
- The driver should emit data as it receives it from the hardware (no caching).
- The driver should emit only data it receives from the hardware (no "filling in the gaps").

The alternative is to use a longer archive interval, one long enough to ensure that all types will be emitted during the interval. 

It's also possible I've completely misunderstood the problem.

Q2: Most likely, your driver is returning a string as a value, instead of a float.

--
You received this message because you are subscribed to the Google Groups "weewx-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to weewx-user+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/weewx-user/9a3f557f-81b5-4b33-b807-fe820394b02bn%40googlegroups.com.

Anders Fosgerau

unread,
Feb 9, 2022, 4:07:55 PM2/9/22
to weewx-user
Thanks a lot for the help Tom!

I’m now typecasting the values, so they not only look like floats but actually are floats. That solved the wind problem.

And a closer reading of the manual revealed that the sensor values are only updated every 7 minutes, so clearly an archive interval of 5 minutes would lead to NULL values simply due to no updates during the archive interval. Changed the archive interval to 10 minutes and problem gone.

Driver still needs some polishing before it’s ready to serve other TFA Weatherhub / Meteoalerts.eu owners/users.

Anders
Reply all
Reply to author
Forward
0 new messages