mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-06 20:28:23 +02:00
156 lines
5.4 KiB
JavaScript
156 lines
5.4 KiB
JavaScript
function parseWeatherStatus(raw) {
|
|
try {
|
|
var data = JSON.parse(String(raw || "{}"))
|
|
return {
|
|
label: data.text || "",
|
|
klass: data.class || ""
|
|
}
|
|
} catch (e) {
|
|
return { label: "", klass: "" }
|
|
}
|
|
}
|
|
|
|
function isFutureForecastDate(dateString, todayString) {
|
|
if (!dateString) return false
|
|
return String(dateString).slice(0, 10) > String(todayString || "")
|
|
}
|
|
|
|
function roundedTemp(value) {
|
|
if (value === undefined || value === null || value === "") return ""
|
|
var n = parseFloat(String(value))
|
|
return isNaN(n) ? "" : String(Math.round(n))
|
|
}
|
|
|
|
function celsiusToFahrenheit(value) {
|
|
if (value === undefined || value === null || value === "") return ""
|
|
var n = parseFloat(String(value))
|
|
return isNaN(n) ? "" : (n * 9 / 5) + 32
|
|
}
|
|
|
|
function formatTemp(value, useImperial) {
|
|
if (value === undefined || value === null || value === "") return ""
|
|
return value + "°" + (useImperial ? "F" : "C")
|
|
}
|
|
|
|
function dayName(dateString, formatter) {
|
|
if (!dateString) return ""
|
|
var d = new Date(dateString + "T12:00:00")
|
|
if (isNaN(d.getTime())) return ""
|
|
if (formatter) return formatter(d)
|
|
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][d.getDay()]
|
|
}
|
|
|
|
function openMeteoForecastDays(dailyForecastReport, todayString) {
|
|
var daily = dailyForecastReport && dailyForecastReport.daily ? dailyForecastReport.daily : null
|
|
if (!daily || !daily.time) return []
|
|
|
|
var result = []
|
|
for (var i = 0; i < daily.time.length && result.length < 3; ++i) {
|
|
var date = daily.time[i]
|
|
if (!isFutureForecastDate(date, todayString)) continue
|
|
|
|
var maxC = daily.temperature_2m_max ? daily.temperature_2m_max[i] : ""
|
|
var minC = daily.temperature_2m_min ? daily.temperature_2m_min[i] : ""
|
|
result.push({
|
|
date: date,
|
|
maxtempC: roundedTemp(maxC),
|
|
mintempC: roundedTemp(minC),
|
|
maxtempF: roundedTemp(celsiusToFahrenheit(maxC)),
|
|
mintempF: roundedTemp(celsiusToFahrenheit(minC)),
|
|
openMeteoWeatherCode: daily.weather_code ? daily.weather_code[i] : null
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
|
|
function wttrNextForecastDays(report, todayString) {
|
|
var days = report && report.weather ? report.weather : []
|
|
var result = []
|
|
for (var i = 0; i < days.length && result.length < 3; ++i) {
|
|
if (isFutureForecastDate(days[i].date, todayString)) result.push(days[i])
|
|
}
|
|
return result
|
|
}
|
|
|
|
function buildForecastDays(report, dailyForecastReport, todayString) {
|
|
var days = openMeteoForecastDays(dailyForecastReport, todayString)
|
|
return days.length > 0 ? days : wttrNextForecastDays(report, todayString)
|
|
}
|
|
|
|
function bareTempForDay(day, kind, useImperial) {
|
|
if (!day) return ""
|
|
var v = useImperial
|
|
? (kind === "max" ? day.maxtempF : day.mintempF)
|
|
: (kind === "max" ? day.maxtempC : day.mintempC)
|
|
if (v === undefined || v === null || v === "") return ""
|
|
return v + "°"
|
|
}
|
|
|
|
function dayIcon(day) {
|
|
if (!day) return ""
|
|
if (day.openMeteoWeatherCode !== undefined && day.openMeteoWeatherCode !== null)
|
|
return iconForOpenMeteoCode(day.openMeteoWeatherCode)
|
|
if (!day.hourly || day.hourly.length === 0) return ""
|
|
|
|
var best = day.hourly[0]
|
|
var bestDist = 9999
|
|
for (var i = 0; i < day.hourly.length; ++i) {
|
|
var t = parseInt(String(day.hourly[i].time || "0"), 10)
|
|
var dist = Math.abs(t - 1200)
|
|
if (dist < bestDist) {
|
|
bestDist = dist
|
|
best = day.hourly[i]
|
|
}
|
|
}
|
|
return iconForCode(best.weatherCode, false)
|
|
}
|
|
|
|
function iconForOpenMeteoCode(code) {
|
|
var c = parseInt(String(code || "0"), 10)
|
|
if (c === 0) return iconForCode(113, false)
|
|
if (c === 1 || c === 2) return iconForCode(116, false)
|
|
if (c === 3) return iconForCode(119, false)
|
|
if (c === 45 || c === 48) return iconForCode(143, false)
|
|
if (c === 51 || c === 53 || c === 55 || c === 56 || c === 57 || c === 61) return iconForCode(266, false)
|
|
if (c === 63 || c === 65 || c === 66 || c === 67 || c === 80 || c === 81 || c === 82) return iconForCode(308, false)
|
|
if (c === 71 || c === 73 || c === 75 || c === 77 || c === 85 || c === 86) return iconForCode(338, false)
|
|
if (c === 95 || c === 96 || c === 99) return iconForCode(389, false)
|
|
return iconForCode(119, false)
|
|
}
|
|
|
|
function iconForCode(code, night) {
|
|
var c = parseInt(String(code || "0"), 10)
|
|
switch (c) {
|
|
case 113: return night ? "" : ""
|
|
case 116: return night ? "" : ""
|
|
case 119: case 122: return ""
|
|
case 143: case 248: case 260: return ""
|
|
case 176: case 263: case 353: return night ? "" : ""
|
|
case 179: case 227: case 230: case 323: case 326: case 368: return night ? "" : ""
|
|
case 182: case 185: case 281: case 284: case 311: case 314:
|
|
case 317: case 320: case 350: case 362: case 365: case 374: case 377: return ""
|
|
case 200: case 386: case 389: case 392: case 395: return ""
|
|
case 266: case 293: case 296: case 299: case 302: case 305: case 308: case 356: case 359: return ""
|
|
case 329: case 332: case 335: case 338: case 371: return ""
|
|
default: return ""
|
|
}
|
|
}
|
|
|
|
if (typeof module !== "undefined") {
|
|
module.exports = {
|
|
parseWeatherStatus: parseWeatherStatus,
|
|
isFutureForecastDate: isFutureForecastDate,
|
|
roundedTemp: roundedTemp,
|
|
celsiusToFahrenheit: celsiusToFahrenheit,
|
|
formatTemp: formatTemp,
|
|
dayName: dayName,
|
|
openMeteoForecastDays: openMeteoForecastDays,
|
|
wttrNextForecastDays: wttrNextForecastDays,
|
|
buildForecastDays: buildForecastDays,
|
|
bareTempForDay: bareTempForDay,
|
|
dayIcon: dayIcon,
|
|
iconForOpenMeteoCode: iconForOpenMeteoCode,
|
|
iconForCode: iconForCode
|
|
}
|
|
}
|