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

10. März 2026 20:14 Uhr: Von Felix B—— an Felix B——

Nochmal bischen optimiert (z für Zulu) und die Abrufzeit mit eingeblendet, BDE in ECET umbenannt. War kürzlich schon ganz praktisch auch im Anflug die aktive Piste übers Internet schnell mal abzurufen und schon 15min vorher Klarheit zu haben. Habe im Übrigen mal den DWD gebeten die MET-Reports zu veröffentlichen oder zumindest in der Flugwetter-APP verfügbar zu machen, wobei die nicht für schlechten Empfang optimiert ist und mich meist genau dort ausloggt.

// ----------------------------------------------------
// 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 ECET)
// ----------------------------------------------------
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 fetchECET() {
  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 die Zeit für ECET.
        if (parts.length >= 6) {
          return parts[5]
        }
      }
    }
    return "--"
  } catch(e) {
    return "Err"
  }
}
let ecetTime = await fetchECET()

// ----------------------------------------------------
// 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. ECET Text & UTC Einblendung (Rechtsbündig unten)
// ----------------------------------------------------
if (ecetTime) {
  // Aktuelle UTC Zeit generieren
  let timeNow = new Date()
  let utcH = ("0" + timeNow.getUTCHours()).slice(-2)
  let utcM = ("0" + timeNow.getUTCMinutes()).slice(-2)
  let utcTime = utcH + ":" + utcM
  
  // Zwei getrennte Textblöcke für perfekte Ausrichtung
  let labelText = "ECET:\nFROM:"
  let valueText = ecetTime + "ᶻ\n" + utcTime + "ᶻ"

  // Angepasste Box-Größe (100px breit, 30px hoch)
  let bgW = 72
  let bgH = 30
  // Box liegt wieder bündig rechts am Rand
  let bgX = canvasW - bgW
  let bgY = canvasH - bgH

  // Halbtransparenter Hintergrundkasten
  let bgRect = new Rect(bgX, bgY, bgW, bgH)
  ctx.setFillColor(new Color("000000", 0.4))
  ctx.fillRect(bgRect)

  // Globale Texteinstellungen
  ctx.setFont(Font.boldSystemFont(9))
  ctx.setTextColor(Color.white())
  
  // 1. Spalte: Labels (Linksbündig zeichnen) - Textfeld startet um 2 Pixel weiter links als vorher (jetzt bgX + 4 statt bgX + 6)
  ctx.setTextAlignedLeft()
  let rectLabels = new Rect(bgX + 1, bgY + 3, bgW - 10, bgH)
  ctx.drawTextInRect(labelText, rectLabels)

  // 2. Spalte: Zeiten (Rechtsbündig zeichnen) - Rechte Kante rückt um genau 2 Pixel nach links
  ctx.setTextAlignedRight()
  let rectValues = new Rect(bgX + 1, bgY + 3, bgW - 10, bgH)
  ctx.drawTextInRect(valueText, rectValues)
}

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

IMG_9648copy.jpg


1 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