stato del mare: previsione onde Open-Meteo + scala Douglas (oggi/domani), EN/IT, context Sea

This commit is contained in:
2026-09-02 14:09:04 +02:00
parent 60c777e650
commit 09ce52a1c6
4 changed files with 124 additions and 0 deletions
+79
View File
@@ -91,11 +91,71 @@ Page {
curveInfo.text = qsTr("Z₀ %1 m · 7 harmonic constituents").arg(port[4][0].toFixed(2))
}
cv.requestPaint()
seaState()
} catch (e) {
console.log("[tide] refresh error:", e)
}
}
function seaFail() {
seaLabel.text = qsTranslate("Sea", "Unavailable (offline)")
seaLabel.color = Theme.secondaryColor
seaSub.text = ""
}
function seaState() {
if (!port) return
console.log("[tide] seaState fetch:", port[0])
var xhr = new XMLHttpRequest()
var done = false
var to = setTimeout(function() {
if (!done) {
done = true
console.log("[tide] seaState timeout")
seaFail()
}
}, 12000)
xhr.open("GET",
"https://marine-api.open-meteo.com/v1/marine?latitude=" + port[2]
+ "&longitude=" + port[3]
+ "&daily=wave_height_max&timezone=auto&forecast_days=3",
true)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (done) return
done = true
clearTimeout(to)
console.log("[tide] seaState status:", xhr.status)
if (xhr.status === 200) {
try {
var j = JSON.parse(xhr.responseText)
var wh = j.daily.wave_height_max
if (wh && wh.length > 0) {
var today = wh[0]
var i0 = Tides.douglas(today)
seaLabel.text = seaNames[i0] + " · " + Tides.fmtH(today, page.unit)
seaLabel.color = i0 >= 5 ? Theme.errorColor
: (i0 >= 4 ? Theme.secondaryColor : Theme.highlightColor)
if (wh.length > 1) {
var i1 = Tides.douglas(wh[1])
seaSub.text = qsTranslate("Sea", "Tomorrow") + ": " + seaNames[i1]
+ " · " + Tides.fmtH(wh[1], page.unit)
seaSub.color = Theme.secondaryColor
} else {
seaSub.text = ""
}
return
}
} catch (e) {
console.log("[tide] seaState parse err:", e)
}
}
seaFail()
}
}
xhr.send()
}
property var moonNames: [
qsTr("New moon"), qsTr("Waxing crescent"), qsTr("First quarter"), qsTr("Waxing gibbous"),
qsTr("Full moon"), qsTr("Waning gibbous"), qsTr("Last quarter"), qsTr("Waning crescent")
@@ -109,6 +169,16 @@ Page {
qsTranslate("Tide", "Sat")
]
// stato del mare: scala Douglas (0-9) — context "Sea" separato:
// "High" qui = "Grosso", non "Alta" degli eventi
property var seaNames: [
qsTranslate("Sea", "Calm"), qsTranslate("Sea", "Calm rippled"),
qsTranslate("Sea", "Smooth wavelets"), qsTranslate("Sea", "Slight"),
qsTranslate("Sea", "Moderate"), qsTranslate("Sea", "Rough"),
qsTranslate("Sea", "Very rough"), qsTranslate("Sea", "High"),
qsTranslate("Sea", "Very high"), qsTranslate("Sea", "Phenomenal")
]
SilicaFlickable {
id: flick
anchors.fill: parent
@@ -297,6 +367,15 @@ Page {
Label { id: rangeLabel; anchors.right: parent.right; anchors.rightMargin: Theme.horizontalPageMargin; anchors.verticalCenter: parent.verticalCenter }
}
// Stato del mare (scala Douglas, previsione onde Open-Meteo)
Item { width: parent.width; height: Theme.itemSizeSmall
Label { text: "🌊 " + qsTranslate("Sea", "Sea state"); color: Theme.secondaryColor; anchors.left: parent.left; anchors.leftMargin: Theme.horizontalPageMargin; anchors.verticalCenter: parent.verticalCenter }
Label { id: seaLabel; text: "…"; anchors.left: parent.left; anchors.leftMargin: Theme.horizontalPageMargin + 130; anchors.right: parent.right; anchors.rightMargin: Theme.horizontalPageMargin; anchors.verticalCenter: parent.verticalCenter; horizontalAlignment: Text.AlignRight; truncationMode: TruncationMode.Fade }
}
Item { width: parent.width; height: Theme.itemSizeSmall
Label { id: seaSub; anchors.left: parent.left; anchors.leftMargin: Theme.horizontalPageMargin + 130; anchors.right: parent.right; anchors.rightMargin: Theme.horizontalPageMargin; anchors.verticalCenter: parent.verticalCenter; horizontalAlignment: Text.AlignRight; font.pixelSize: Theme.fontSizeSmall; truncationMode: TruncationMode.Fade }
}
Item { width: parent.width; height: Theme.paddingLarge }
}
}