# @name Wetter # @desc Wetter, 15-Stunden-Prognose und Mondphase # @author Hank_the_Tank / Codex # @version 3.0 class Weather var st, fc, label, tcol, wic, mic, mday, ticks, busy, age def init() # Farbstufen: Untergrenze, Farbe - dazwischen wird interpoliert self.st = [-12, 0xD977DF, -6, 0x9545BC, -1, 0x4B379C, 0, 0xFEC4FF, 4, 0x31B8DB, 10, 0x31DB8B, 15, 0x6ED228, 21, 0xFFFF28, 27, 0xF87E27, 32, 0xCF3927, 38, 0xA12527] self.fc = [] self.label = store.get("label") self.tcol = store.get("col", 0x666666) self.wic = store.get("icon", "") self.mic = "" self.mday = -1 self.ticks = 0 self.busy = false self.age = 9999 end def on_body(w, status) self.busy = false if w == nil return end var m = re.search("_2m\":([-0-9.]+)", w) var c = re.search("code\":(\\d+)", w) var h = re.search("_2m\":\\[([^\\]]*)", w) if m == nil || c == nil || h == nil return end var t = num(m[1]) if t == nil return end # i == 0 ist die aktuelle Temperatur, danach die Stundenwerte var s = self.st var vals = re.matchall("[-0-9.]+", h[1]) var n = size(vals) if n > 15 n = 15 end var fc = [] var i = 0 while i <= n var v = i == 0 ? t : num(vals[i - 1]) var col = s[1] if v > s[0] var j = 0 while j < 20 && v >= s[j + 2] j += 2 end if j >= 20 col = s[21] else var a = s[j + 1] var b = s[j + 3] var f = (v - s[j]) * 1.0 / (s[j + 2] - s[j]) col = rgb(int(a / 65536 % 256 + (b / 65536 % 256 - a / 65536 % 256) * f), int(a / 256 % 256 + (b / 256 % 256 - a / 256 % 256) * f), int(a % 256 + (b % 256 - a % 256) * f)) end end if i == 0 self.tcol = col else fc.push(col) end i += 1 end self.fc = fc self.label = str(int(t + (t >= 0 ? 0.5 : -0.5))) + "°" var k = int(num(c[1])) var ic = "36637" if k == 0 ic = "53386" elif k <= 2 ic = "2286" elif k == 3 ic = "53384" elif k <= 48 ic = "17055" elif k <= 67 ic = "2720" elif k <= 77 ic = "2289" elif k <= 82 ic = "49300" elif k <= 86 ic = "2289" elif k >= 95 ic = "29839" end self.wic = ic self.age = 0 store.set("label", self.label) store.set("col", self.tcol) store.set("icon", ic) end def loop() var d = day() if d != self.mday self.mday = d var mo = month() var a = int((14 - mo) / 12) var yy = year() + 4800 - a var mm = mo + 12 * a - 3 var f = (d + int((153 * mm + 2) / 5) + 365 * yy + int(yy / 4) - int(yy / 100) + int(yy / 400) - 2483595) / 29.53058867 f -= int(f) var ic = "2317" if f < 0.03 || f >= 0.97 ic = "2318" elif f < 0.22 ic = "2319" elif f < 0.28 ic = "2320" elif f < 0.48 ic = "2321" elif f < 0.52 ic = "2314" elif f < 0.72 ic = "2315" elif f < 0.78 ic = "2316" end self.mic = ic end self.age += 1 if self.ticks <= 0 self.ticks = 300 if !self.busy self.busy = true http.get("https://api.open-meteo.com/v1/forecast" + # ---- Standort hier setzen ---- "?latitude=52.52&longitude=13.40" + # ------------------------------ "¤t=temperature_2m,weather_code&hourly=temperature_2m" + "&forecast_hours=15&timeformat=unixtime&timezone=auto", / b, st -> self.on_body(b, st), {'find': "\"current\":", 'keep': 640}) end end self.ticks -= 1 end def draw() clear() if self.label == nil text(6, 6, "...", 0x666666) return end if !icon(self.wic, 0, 0) circle_fill(4, 4, 3, 0xFFCC00) end text(9 + int((14 - text_ink_width(self.label)) / 2), 6, self.label, self.tcol) icon(self.mic, 23, 0) var i = 0 var n = size(self.fc) while i < n pixel(8 + i, 7, self.fc[i]) i += 1 end if self.age > 1200 pixel(width() - 1, height() - 1, 0xFF0000) end end def on_button(btn) if btn == "select" self.ticks = 0 end end end return Weather()