I added this to the new-belchertown skin.
Straightforward.
Add user.wetbulb.WetBulbService to data_services line
Add wetbulb.py to your weewx-data/bin/user directory
Drop index_hook_after_charts.inc into /skins/new-belchertown
Restart weewx and then weectl reports run

Look at the bottom of the page and you should see the status




On Tuesday, June 23, 2026 at 3:35:59 PM UTC-4 David Hathaway wrote:

> Very interesting!  I have been asking an AI agent to estimate the WBGT for 
> me, and now I asked it what it was using.  It uses the Stull formula and 
> then a crude radiant heat adjustment.  I think it is close enough for me to 
> caution my wife to come in frequently so she doesn't perish.  I'm 
> frequently surprised that the WBGT is lower than our actual temperature and 
> far below the "feel's like" that we are accustomed to.
>
> The agent says:
>
> *WBGT Calculation – Full Explanation*
>
> The process follows the weather-wbgt-safety skill, which uses local WeeWX 
> data and standard approximations suitable for practical heat-stress 
> assessment.
>
> *Step 1: Data Source*
> - The local RSS file at /www/rss.xml is read directly.
> - Current values extracted: 
> – Outside Temperature (*T*): 95.4 °F 
> – Outside Humidity (*RH*): 65 % 
> – Wind: calm (not used in the WBGT formula here) 
> – Timestamp: 13:40 CDT (used to determine daylight)
>
> *Step 2: Wet-Bulb Temperature (Tw)*
> Wet-bulb temperature is calculated using *Stull’s approximation* (a 
> reliable, widely used empirical formula that avoids needing a full 
> psychrometric chart).
>
> 1. Convert *T* from °F to °C. 
> 2. Apply Stull’s formula (all temperatures in °C, RH in %):
>
> Tw = T × atan(0.151977 × √(RH + 8.313659)) + atan(T + RH) − atan(RH − 
> 1.676331) + 0.00391838 × (RH¹·⁵) × atan(0.023101 × RH) − 4.686035 
>
> 3. Convert the resulting *Tw* back to °F.
>
> *Result:* Wet-bulb temperature = 85.3 °F
>
> *Step 3: Daylight Adjustment for WBGT*
> - Daylight is defined locally as approximately 6:30 AM – 8:15 PM in summer 
> for Sugar Land, TX.
> - Because it is daytime and the sun is contributing radiant heat, the 
> following adjustment is applied:
>
> WBGT ≈ Tw + ((T − Tw) × 0.35) + 3.5 
>
> This accounts for the additional heat load from direct sunlight.
>
> *Result:* WBGT = 92.3 °F
>
> *Step 4: Risk Classification*
> The value is compared against standard thresholds (in °F):
>
> - < 80 → Low 
> - 80–85 → Moderate 
> - 85–88 → High 
> - 88–90 → Very High 
> - > 90 → Extreme
>
> At 92.3 °F the conditions fall into the *Extreme* category, triggering 
> the safety guidance.
>
> This method gives a practical, conservative estimate without requiring 
> specialized instruments (black-globe thermometer, etc.). It is intended for 
> personal decision-making rather than official occupational safety 
> compliance.
> On Tuesday, June 23, 2026 at 2:19:25 PM UTC-5 Rainer Lang wrote:
>
>> the story is rather simple - it refers to how WGBT is determined and what 
>> is supported by them.
>> The general formula for determining WBGT outdoors is:
>> WGBT = 0.7 x Tnwb + 0.2 x Tg + 0.1 x Ta 
>> where nbw is natural wet bulb, g is BGT and a is outdoor temperature
>> - to get  Ta  in an Ecowitt context, you need an outdoor T&H sensor 
>> (e.g. WH32)
>> - to get Tg  in an Ecowitt context, you need a WN38 Black Globe 
>> Temperature sensor
>> - to get Tnwb there is no sensor provided - therefore an approximation 
>> method is being used
>> only in this combination Ecowitt provides WBGT data
>> and as WBGT has a medical dimension, the disclaimer is on there in their 
>> (Ecowitt) web shop
>>
>> there are basically two approximation methods for determining Tnwb and Tg 
>> 1. the so-called Stull formula which uses temperature, humidity and air 
>> pressure (and derived entities like water saturation pressure)
>> 2. the so-called Lijlegren approximation which also uses wind speed and, 
>> depending on the accuracy targeted, also sometimes solar radiation values 
>> (direct, indirect, at different wave-lengths ...)
>>
>> 1. the Stull approximation implemented in the firmware now (and used by 
>> many others) can lead to a deviation of up to 3° C
>> 2. is quite a sophisticated approach with several iterations, depending 
>> on if the approach is used for Tnwb only or for  Tnwb +  Tg and if solar 
>> values are included or not
>>
>>
>> to program the full Lijegren approach to reach a < 0.1% deviation from a 
>> nbw-sensor, a coding of 300 - 400 lines of code is needed due to repetetive 
>> iterations (so 'they' say)
>> - for so-called "medical" (health related) purposes, a simplified 
>> Lijlegren approach can be used also using wind speed and it produces a 
>> deviation of < 0.3° C - that's sufficient for the WGBT tiers/windows used 
>> in different areas
>> - Ecowitt is considering to replace the Stull formula used now by a 
>> simplified Llijlegren approach including wind speed to reach a higher 
>> degree of accuracy 
>> so, the accuracy of WBGT values provided by any piece of weather station 
>> firmware or data logging software (like weewx) will depend on the approach 
>> used.
>>
>>
>> On 23.06.2026 20:38, David Hathaway wrote:
>>
>> Thanks for the discussion pointer.  I'll go snoop.
>>
>> On Tuesday, June 23, 2026 at 1:09:37 PM UTC-5 Vince Skahan wrote:
>>
>>> I recently saw mention of https://shop.ecowitt.com/products/wn38  which 
>>> has a disclaimer that I didn't look into further. 
>>>
>>> *"The WN38 Black Globe Thermometer measures and displays the black globe 
>>> temperature only, which can be viewed on the LCD screen or through the 
>>> Ecowitt or WS View Plus app.* 
>>>
>>> *To display WBGT (Wet Bulb Globe Temperature) data in the app, the WN38 
>>> must be used together with an Ecowitt outdoor temperature and humidity 
>>> sensor from either an outdoor array or a WN32(WN31 is not feasible)."*
>>>
>>> There is a lot of discussion at 
>>> https://www.wxforum.net/index.php?topic=49316.0 which might be worth a 
>>> read.  Hope this helps.
>>> On Wednesday, June 10, 2026 at 10:03:28 AM UTC-7 David Hathaway wrote:
>>>
>>>> There is a 'wetbulp.py' (note the p) in this group that calculates it 
>>>> as a xtype_service.  This conversation,
>>>>
>>>> https://groups.google.com/g/weewx-user/c/FntQukhWY00/m/lM53yFt7AwAJ
>>>>
>>>>
>>>> On Wednesday, June 10, 2026 at 11:48:33 AM UTC-5 Vince Skahan wrote:
>>>>
>>>>> Quick search seems to say a WeatherFlow Tempest station has this, but 
>>>>> I can't find it mentioned in any of their API so I don't see a way to get 
>>>>> it into weewx for this one model station - 
>>>>> https://community.tempest.earth/t/wet-bulb-globe-temperature/14386/11 
>>>>>
>>>>> Other threads and docs with the formula seem to say you need special 
>>>>> sensors for this, so I can't speculate how WeatherFlow fakes something to 
>>>>> generate that item.
>>>>>
>>>>> On Wednesday, June 10, 2026 at 8:36:45 AM UTC-7 David Hathaway wrote:
>>>>>
>>>>>> As the FIFA World Cup (tm) ramps up, we here in Houston are getting a 
>>>>>> load of notices about how there is a mandatory water break in matches, 
>>>>>> even 
>>>>>> though it is played indoors. :-/ As I discussed this with my friend the 
>>>>>> sports trainer, he mentioned that Texas now has a rule that they must do 
>>>>>> certain things according to the WBGT. 
>>>>>>
>>>>>> I have searched here for wet bulb additions to WeeWx.  I see 
>>>>>> discussions from 2024 and wonder if there is someone with a more recent 
>>>>>> idea about implementing this.  Does anyone calculate the Risk Level and 
>>>>>> provide Guidance?
>>>>>>
>>>>>> I am trying out an agentic Ai to read the RSS XML feed; It loves this 
>>>>>> format.  I've not messed with the RSS export.  Is there some intrisic 
>>>>>> gotcha?  I really only care about current values.
>>>>>>
>>>>>> Dave
>>>>>>
>>>>> -- 
>> 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 [email protected].
>> To view this discussion visit 
>> https://groups.google.com/d/msgid/weewx-user/29861e34-51f9-4df4-86e0-c9e06cdbdda0n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/weewx-user/29861e34-51f9-4df4-86e0-c9e06cdbdda0n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>>

-- 
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 [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/weewx-user/645833de-b0f5-40fb-95e6-24a985eed151n%40googlegroups.com.
import math
import weewx
import weewx.engine
from weewx.xtypes import XType

# 1. The Service that loads safely into the WeeWX 5 Engine pipeline
class WetBulbService(weewx.engine.StdService):
    def __init__(self, engine, config_dict):
        super(WetBulbService, self).__init__(engine, config_dict)
        # Register the actual XType calculator safely
        weewx.xtypes.xtypes.append(WetBulbImpl())

# 2. The actual calculator implementing the required WeeWX 5 XType spec
class WetBulbImpl(XType):
    def get_scalar(self, data_type, record, db_manager=None):
        if data_type != 'wetbulb_risk':
            raise weewx.UnknownType(data_type)

        try:
            # Safely fetch fields using dict get() to avoid KeyError if missing
            temp_f = record.get('outTemp')
            rh = record.get('outHumidity')
            
            if temp_f is None or rh is None:
                return (None, "degree_F", "group_temperature")
            
            # Convert to Celsius for Stull's Formula
            t = (float(temp_f) - 32.0) * 5.0 / 9.0
            
            # Stull's Formula
            tw_c = (t * math.atan(0.151977 * math.pow(rh + 8.313659, 0.5)) 
                    + math.atan(t + rh) 
                    - math.atan(rh - 1.676331) 
                    + 0.00391838 * math.pow(rh, 1.5) * math.atan(0.023101 * rh) 
                    - 4.686035)
            
            # Convert back to Fahrenheit
            tw_f = (tw_c * 9.0 / 5.0) + 32.0
            return (tw_f, "degree_F", "group_temperature")
            
        except Exception:
            return (None, "degree_F", "group_temperature")

    # Required stub methods so WeeWX doesn't throw errors during daily summary generations
    def get_aggregate(self, data_type, timespan, aggregate_type, db_manager, **kwargs):
        raise weewx.UnknownType(data_type)

    def get_series(self, data_type, timespan, db_manager, aggregate_type=None, aggregate_interval=None, **kwargs):
        raise weewx.UnknownType(data_type)

Attachment: index_hook_after_charts.inc
Description: Binary data

Reply via email to