3.8.5
Correct 'Shade' temps for night
This commit is contained in:
+20
-12
@@ -14,7 +14,7 @@
|
||||
import {
|
||||
vaporPressureHpa, solarElevationDeg, calcTmrt, utciApprox,
|
||||
calcConcreteTempPass, calcVehicleInteriorTempPass,
|
||||
calcIndoorTempPass, calcManagedIndoorTempPass, calcShadeAirTemp,
|
||||
calcIndoorTempPass, calcManagedIndoorTempPass, calcShadeAirTemp, calcShadeFeltTemp,
|
||||
calcFurSurfaceTempPass,
|
||||
} from './physics.js';
|
||||
import { windCompass8, uvSplit, cloudCategory, precipPenalty, sunburnMinutes, burnLabel, FUR_COLORS } from './utils.js';
|
||||
@@ -84,15 +84,22 @@ export function buildHourlyRows({ forecast, airQuality, location, vehicleType, v
|
||||
const difEnv = dif * env.difFactor;
|
||||
const globEnv = glob * env.globFactor;
|
||||
// concreteT is now stamped in the two-pass section below (thermal lag).
|
||||
// Shade air temp: the air you'd feel in this Solar Model's typical shade
|
||||
// (building shadow, beach umbrella, canopy...). Shares SunSoak's TaEnv
|
||||
// baseline and env-reduced radiation, so the two columns stay consistent.
|
||||
const shadeT = calcShadeAirTemp(TaEnv, dirEnv + difEnv * 0.2, va, elev, env.shade);
|
||||
// vehicleT is stamped in the two-pass section below (thermal lag).
|
||||
const eh = vaporPressureHpa(Ta, RH);
|
||||
const Tmrt = calcTmrt(TaEnv, dirEnv, difEnv, globEnv, elev);
|
||||
const utci = utciApprox(TaEnv, Tmrt, va, eh);
|
||||
const utciAdj = utci + precipPenalty(precip, snow, va);
|
||||
// Shade air temp: what a thermometer in this Solar Model's typical shade
|
||||
// (building shadow, beach umbrella, canopy...) would read. Shares
|
||||
// SunSoak's TaEnv baseline and env-reduced radiation, so the two stay
|
||||
// consistent. Pet Shade reads this directly; the human Shade column
|
||||
// below turns it into a felt temperature first.
|
||||
const shadeAirT = calcShadeAirTemp(TaEnv, dirEnv + difEnv * 0.2, va, elev, env.shade);
|
||||
// Shade (felt): SunSoak with the direct beam taken away — still outdoors,
|
||||
// so the same wind, humidity and rain penalty apply. See
|
||||
// calcShadeFeltTemp() for why this is a felt number and not the air temp.
|
||||
const shadeT = calcShadeFeltTemp(shadeAirT, difEnv, va, eh, elev, env.shade)
|
||||
+ precipPenalty(precip, snow, va);
|
||||
// Derived
|
||||
const compass = windCompass8(wd);
|
||||
const { uvA, uvB } = uvSplit(uv, elev);
|
||||
@@ -154,10 +161,11 @@ export function buildHourlyRows({ forecast, airQuality, location, vehicleType, v
|
||||
uv, uvA, uvB,
|
||||
precip, precipProb, lightning, cape, snow,
|
||||
soilT0, soilT6, soilM, shadeT,
|
||||
// Pet Shade reads the same hourly value as Shade but aggregates as a
|
||||
// MEAN rather than a worst case, so it needs its own field to diverge
|
||||
// from shadeT at 2h/3h/4h. Same for pawT vs concreteT below.
|
||||
petShadeT: shadeT,
|
||||
// Pet Shade stays on the shade AIR temperature: the human Shade column
|
||||
// is a UTCI felt number on a human comfort scale, which says nothing
|
||||
// useful about a cat. It also aggregates as a MEAN rather than a worst
|
||||
// case, so it needs its own field either way (same for pawT/concreteT).
|
||||
petShadeT: shadeAirT,
|
||||
effectiveRad,
|
||||
elev, Tmrt, utci, utciAdj, eh, compass,
|
||||
visKm, aqi,
|
||||
@@ -723,7 +731,7 @@ export function computeGlanceSummary(todayRows, profile, variant, skinType, cols
|
||||
// ── Pets (cats / small dogs) ────────────────────────────────────────────
|
||||
if (profile === 'pets') {
|
||||
const peakFur = peakRow('furSurfaceT');
|
||||
const peakShade = peakRow('shadeT');
|
||||
const peakShade = peakRow('petShadeT');
|
||||
const peakIndoor = peakRow('indoorT');
|
||||
const maxPollen = Math.max(0, ...todayRows.map(r => r.grassPollen ?? 0));
|
||||
const peakAqi = Math.max(0, ...todayRows.map(r => r.aqi ?? 0));
|
||||
@@ -740,8 +748,8 @@ export function computeGlanceSummary(todayRows, profile, variant, skinType, cols
|
||||
...(show('petShadeT') ? [{
|
||||
icon: '🌳',
|
||||
label: 'Shade for pet',
|
||||
value: peakShade ? `${Math.round(peakShade.shadeT)}° at ${hhmm(peakShade.iso)}` : '-',
|
||||
alert: !!(peakShade && peakShade.shadeT >= 26),
|
||||
value: peakShade ? `${Math.round(peakShade.petShadeT)}° at ${hhmm(peakShade.iso)}` : '-',
|
||||
alert: !!(peakShade && peakShade.petShadeT >= 26),
|
||||
grp: 'ambient',
|
||||
}] : []),
|
||||
...(show('petHomeT') ? [{
|
||||
|
||||
Reference in New Issue
Block a user