Login: 
Passwort: 
Neuanmeldung 
Passwort vergessen



Das neue Heft erscheint am 1. März
LBA Medical: Runder Tisch mit einer Ecke
Ein Jahr TwinCo
Landung neben der Landebahn
Hebrideninseln Coll und Colonsay
Kleiner Reiseführer für Oshkosh
Unfallschwerpunkt PC-12: Loss of Control
Engagierter Journalismus aus Sicht des eigenen Cockpits
Engagierter Journalismus aus Sicht des eigenen Cockpits
Sortieren nach:  Datum - neue zuerst |  Datum - alte zuerst |  Bewertung

Sonstiges | Wetter und Webcam Widget unter iOS  
26. Februar 2026 14:27 Uhr: Von Frank Heßler  Bewertung: +8.00 [8]

Manchmal sind die Tage, an denen man nicht fliegen kann, ja doch ganz interessant. Ich wollte das lokale Wetter in Egelsbach etwas bequemer im Blick behalten. Der lokale Wetterreport ist zwar sehr hilfreich, über die DWD App aber nicht direkt abrufbar und die Webseite fand ich ehrlich gesagt etwas umständlich.

Egelsbach stellt ein schönes JPG Bild mit dem aktuellen Wetter zur Verfügung. Also habe ich nach einer Möglichkeit gesucht, dieses Bild als Widget auf meinem iPhone anzuzeigen. Wirklich brauchbare Lösungen habe ich spontan nicht gefunden. Im Prinzip müsste das ja mit jedem öffentlichen Webcam Bild funktionieren. Wie macht ihr das?

iOS Homescreen Widget

Ich habe mir dann die App Scriptable installiert. Dort kann man ein eigenes Script anlegen, zum Beispiel mit dem Namen EDFE Wetter, und folgenden Code einfügen:

let url = "https://images.egelsbach-airport.com/METREPEgelsbach/metrep.jpg"

// Cache umgehen
let fullUrl = url + "?t=" + Date.now()

if (config.runsInWidget) {
  // WIDGET ANSICHT
  let req = new Request(fullUrl)
  let img = await req.loadImage()

  let widget = new ListWidget()
  widget.backgroundColor = new Color("#000000")

  let image = widget.addImage(img)
  image.applyFittingContentMode()
  image.centerAlignImage()

  widget.refreshAfterDate = new Date(Date.now() + 5 * 60 * 1000)

  Script.setWidget(widget)
  Script.complete()

} else {
  // VOLLBILD ANSICHT BEIM ANTIPPEN
  let req = new Request(fullUrl)
  let img = await req.loadImage()

  let view = new WebView()

  // Bild in voller Breite anzeigen
  let html = `
  <html>
    <head>
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <style>
        body { margin:0; background:black; display:flex; justify-content:center; align-items:center; }
        img { width:100%; height:auto; }
      </style>
    </head>
    <body>
      <img src="${fullUrl}">
    </body>
  </html>
  `

  await view.loadHTML(html)
  await view.present(true)
}

Mit Done speichern. Anschließend auf den Homescreen wechseln, in den Bearbeitungsmodus gehen, Widget hinzufügen, Scriptable auswählen, die gewünschte Größe wählen und das Widget platzieren. Danach lässt sich das Widget konfigurieren, indem man das zuvor angelegte Script auswählt.

Und tatsächlich, es funktioniert. Das aktuelle Wetterbild wird direkt im Widget angezeigt. Wenn man drauf klickt sieht man das Bild größer.

Vermutlich gibt es dafür längst eine einfachere Lösung, aber das Wetter war ohnehin nicht fliegbar und ich hatte gerade etwas Zeit zum Basteln.




   Back      Slideshow
      
Forward   
1 / 4

20260226_132111000_iOS.jpg



26. Februar 2026 19:29 Uhr: Von Felix B—— an Frank Heßler Bewertung: +1.00 [1]

super idee, mit ai: plus webcam, ecet und ohnw schwarze balken:

// ----------------------------------------------------
// URLs
// ----------------------------------------------------
let urlMetar = "https://images.egelsbach-airport.com/METREPEgelsbach/metrep.jpg"
let urlCam   = "https://images.egelsbach-airport.com/WebCamEgelsbach/Wetter.jpg"
let urlDWD   = "https://www.dwd.de/DE/fachnutzer/luftfahrt/teaser/luftsportberichte/edfe/node.html"

// ----------------------------------------------------
// EINSTELLUNGEN
// ----------------------------------------------------
let cropWidget     = 30
let cropFullscreen = 80
let safeAreaMargin = 00
// ----------------------------------------------------

// ----------------------------------------------------
// LOGIK
// ----------------------------------------------------
let isFullscreen = (args.queryParameters["fullscreen"] === "true")
let showWidget   = config.runsInWidget || !isFullscreen

let activeCrop   = showWidget ? cropWidget : cropFullscreen
let activeMargin = showWidget ? safeAreaMargin : 0

// ----------------------------------------------------
// WIDGET-GRÖSSE (IN PUNKTEN!)
// ----------------------------------------------------
let widgetWidthPt  = 329
let widgetHeightPt = 155

let canvasW = widgetWidthPt
let canvasH = widgetHeightPt

// ----------------------------------------------------
// DATEN LADEN (Bilder & DWD BDE)
// ----------------------------------------------------
let reqMetar = new Request(urlMetar + "?t=" + Date.now())
let imgMetar = await reqMetar.loadImage()

let reqCam = new Request(urlCam + "?t=" + Date.now())
let imgCam = await reqCam.loadImage()

async function fetchBDE() {
  try {
    let req = new Request(urlDWD)
    let html = await req.loadString()
    
    let now = new Date()
    let year = now.getFullYear()
    let month = ("0" + (now.getMonth() + 1)).slice(-2)
    let day = ("0" + now.getDate()).slice(-2)
    let todayStr = year + "-" + month + "-" + day

    let rows = html.split("\n")
    for (let row of rows) {
      if (row.includes(todayStr)) {
        let cleanRow = row.replace(/<[^>]*>/g, " ").trim()
        let parts = cleanRow.split(/\s+/).filter(p => p.length > 0)
        
        // Index 5 ist 17:35
        if (parts.length >= 6) {
          // Wieder einzeilig
          return "BDE: " + parts[5]
        }
      }
    }
    return "BDE: --"
  } catch(e) {
    return "BDE: Err"
  }
}
let bdeText = await fetchBDE()

// ----------------------------------------------------
// DRAW CONTEXT
// ----------------------------------------------------
let ctx = new DrawContext()
ctx.size = new Size(canvasW, canvasH)
ctx.respectScreenScale = true
ctx.opaque = true

// ----------------------------------------------------
// 1. Webcam Hintergrund
// ----------------------------------------------------
let camW = imgCam.size.width
let camH = imgCam.size.height

let scaleCam = Math.max(canvasW / camW, canvasH / camH)
let drawCamW = camW * scaleCam
let drawCamH = camH * scaleCam

let drawCamX = (canvasW - drawCamW) / 2
let drawCamY = (canvasH - drawCamH) / 2

ctx.drawImageInRect(imgCam, new Rect(drawCamX, drawCamY, drawCamW, drawCamH))

// ----------------------------------------------------
// 2. METAR Overlay
// ----------------------------------------------------
let metarW = imgMetar.size.width
let metarH = imgMetar.size.height

let scaleMetar = canvasH / metarH
let drawMetW   = metarW * scaleMetar
let drawMetH   = canvasH

let shiftLeft  = activeCrop * scaleMetar
let drawMetX   = -shiftLeft + activeMargin
let drawMetY   = 0

ctx.drawImageInRect(imgMetar, new Rect(drawMetX, drawMetY, drawMetW, drawMetH))

// ----------------------------------------------------
// 3. BDE Text Einblendung (Rechtsbündig unten)
// ----------------------------------------------------
if (bdeText) {
  ctx.setFont(Font.boldSystemFont(10))
  ctx.setTextColor(Color.white())
  ctx.setTextAlignedRight()
  
  // Unten rechts positionieren (Höhe des Canvas minus 30 Pixel)
  let rectText = new Rect(canvasW - 110, canvasH - 30, 100, 20)
  ctx.drawTextInRect(bdeText, rectText)
}

let compositeImg = ctx.getImage()

// ----------------------------------------------------
// AUSGABE
// ----------------------------------------------------
if (showWidget) {

  let widget = new ListWidget()
  widget.url =
    "scriptable:///run?scriptName=" +
    encodeURIComponent(Script.name()) +
    "&fullscreen=true"

  widget.backgroundImage = compositeImg
  widget.refreshAfterDate = new Date(Date.now() + 5 * 60 * 1000)

  if (config.runsInWidget) {
    Script.setWidget(widget)
  } else {
    await widget.presentMedium()
  }

  Script.complete()

} else {

  let view = new WebView()

  let imgData = Data.fromPNG(compositeImg).toBase64String()
  let base64Url = "data:image/png;base64," + imgData

  let html = `
  <html>
    <head>
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <style>
        body {
          margin:0;
          background:black;
          display:flex;
          justify-content:center;
          align-items:center;
          min-height:100vh;
        }
        img {
          width:100%;
          height:auto;
        }
      </style>
    </head>
    <body>
      <img src="${base64Url}">
    </body>
  </html>
  `

  await view.loadHTML(html)
  await view.present(true)
  Script.complete()
}


1 / 1

Screenshot2026-02-26at20.13.58.jpg

27. Februar 2026 14:51 Uhr: Von Frank Heßler an Felix B——

Ja super! Das ist wirklich das Luxusupgrade! Vielen Dank hierfür!

Vorgestern 18:21 Uhr: Von Felix B—— an Frank Heßler

Leider habe ich es mit diversen AI Anfragen nicht hinbekommen die Auflösung zu erhöhen in der Widget-Darstellung. In Scriptable wird das Bild höheraufgelöst angezeigt. Vielleicht bekommt das ja die Community hin :-)


4 Beiträge Seite 1 von 1

 

Home
Impressum
© 2004-2026 Airwork Press GmbH. Alle Rechte vorbehalten. Vervielfältigung nur mit Genehmigung der Airwork Press GmbH. Die Nutzung des Pilot und Flugzeug Internet-Forums unterliegt den allgemeinen Nutzungsbedingungen (hier). Es gelten unsere Datenschutzerklärung unsere Allgemeinen Geschäftsbedingungen (hier). Kartendaten: © OpenStreetMap-Mitwirkende, SRTM | Kartendarstellung: © OpenTopoMap (CC-BY-SA) Hub Version 14.29.06
Zur mobilen Ansicht wechseln
Seitenanfang