mirror of
https://github.com/weewx/weewx.git
synced 2026-04-20 01:26:56 -04:00
117 lines
4.3 KiB
Python
117 lines
4.3 KiB
Python
#
|
|
# Copyright (c) 2020 Tom Keffer <tkeffer@gmail.com>
|
|
#
|
|
# See the file LICENSE.txt for your full rights.
|
|
#
|
|
"""This example shows how to extend the XTypes system with a new type, vapor_p, the vapor
|
|
pressure of water.
|
|
|
|
REQUIRES WeeWX V4.2 OR LATER!
|
|
|
|
To use:
|
|
1. Stop weewxd
|
|
2. Put this file in your user subdirectory.
|
|
3. In weewx.conf, subsection [Engine][[Services]], add VaporPressureService to the list
|
|
"xtype_services". For example, this means changing this
|
|
|
|
[Engine]
|
|
[[Services]]
|
|
xtype_services = weewx.wxxtypes.StdWXXTypes, weewx.wxxtypes.StdPressureCooker, weewx.wxxtypes.StdRainRater
|
|
|
|
to this:
|
|
|
|
[Engine]
|
|
[[Services]]
|
|
xtype_services = weewx.wxxtypes.StdWXXTypes, weewx.wxxtypes.StdPressureCooker, weewx.wxxtypes.StdRainRater, user.vaporpressure.VaporPressureService
|
|
|
|
4. Optionally, add the following section to weewx.conf:
|
|
[VaporPressure]
|
|
algorithm = simple # Or tetens
|
|
|
|
5. Restart weewxd
|
|
|
|
"""
|
|
import math
|
|
|
|
import weewx
|
|
import weewx.units
|
|
import weewx.xtypes
|
|
from weewx.engine import StdService
|
|
from weewx.units import ValueTuple
|
|
|
|
|
|
class VaporPressure(weewx.xtypes.XType):
|
|
|
|
def __init__(self, algorithm='simple'):
|
|
# Save the algorithm to be used.
|
|
self.algorithm = algorithm.lower()
|
|
|
|
def get_scalar(self, obs_type, record, db_manager):
|
|
# We only know how to calculate 'vapor_p'. For everything else, raise an exception UnknownType
|
|
if obs_type != 'vapor_p':
|
|
raise weewx.UnknownType(obs_type)
|
|
|
|
# We need outTemp in order to do the calculation.
|
|
if 'outTemp' not in record or record['outTemp'] is None:
|
|
raise weewx.CannotCalculate(obs_type)
|
|
|
|
# We have everything we need. Start by forming a ValueTuple for the outside temperature.
|
|
# To do this, figure out what unit and group the record is in ...
|
|
unit_and_group = weewx.units.getStandardUnitType(record['usUnits'], 'outTemp')
|
|
# ... then form the ValueTuple.
|
|
outTemp_vt = ValueTuple(record['outTemp'], *unit_and_group)
|
|
|
|
# Both algorithms need temperature in Celsius, so let's make sure our incoming temperature
|
|
# is in that unit. Use function convert(). The results will be in the form of a ValueTuple
|
|
outTemp_C_vt = weewx.units.convert(outTemp_vt, 'degree_C')
|
|
# Get the first element of the ValueTuple. This will be in Celsius:
|
|
outTemp_C = outTemp_C_vt[0]
|
|
|
|
if self.algorithm == 'simple':
|
|
# Use the "Simple" algorithm.
|
|
# We need temperature in Kelvin.
|
|
outTemp_K = weewx.units.CtoK(outTemp_C)
|
|
# Now we can use the formula. Results will be in mmHg. Create a ValueTuple out of it:
|
|
p_vt = ValueTuple(math.exp(20.386 - 5132.0 / outTemp_K), 'mmHg', 'group_pressure')
|
|
elif self.algorithm == 'tetens':
|
|
# Use Teten's algorithm.
|
|
# Use the formula. Results will be in kPa:
|
|
p_kPa = 0.61078 * math.exp(17.27 * outTemp_C_vt[0] / (outTemp_C_vt[0] + 237.3))
|
|
# Form a ValueTuple
|
|
p_vt = ValueTuple(p_kPa, 'kPa', 'group_pressure')
|
|
else:
|
|
# Don't recognize the exception. Fail hard:
|
|
raise ValueError(self.algorithm)
|
|
|
|
# We have the vapor pressure as a ValueTuple. Convert it back to the units used by
|
|
# the incoming record and return it
|
|
return weewx.units.convertStd(p_vt, record['usUnits'])
|
|
|
|
|
|
class VaporPressureService(StdService):
|
|
""" WeeWX service whose job is to register the XTypes extension VaporPressure with the
|
|
XType system.
|
|
"""
|
|
|
|
def __init__(self, engine, config_dict):
|
|
super(VaporPressureService, self).__init__(engine, config_dict)
|
|
|
|
# Get the desired algorithm. Default to "simple".
|
|
try:
|
|
algorithm = config_dict['VaporPressure']['algorithm']
|
|
except KeyError:
|
|
algorithm = 'simple'
|
|
|
|
# Instantiate an instance of VaporPressure:
|
|
self.vp = VaporPressure(algorithm)
|
|
# Register it:
|
|
weewx.xtypes.xtypes.append(self.vp)
|
|
|
|
def shutDown(self):
|
|
# Remove the registered instance:
|
|
weewx.xtypes.xtypes.remove(self.vp)
|
|
|
|
|
|
# Tell the unit system what group our new observation type, 'vapor_p', belongs to:
|
|
weewx.units.obs_group_dict['vapor_p'] = "group_pressure"
|