Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Spotting Israel
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A single-purpose site for plane spotters at Ben Gurion Airport (TLV/LLBG): it works
out which runways are actually being used for landings and takeoffs at this moment,
and tells you where to stand.
No build step, no backend. Open index.html or serve the folder statically.
No free source publishes TLV's runway configuration — ATIS on 132.500 is voice only —
so the app derives it from live traffic.
Every 20 seconds it pulls all aircraft within 20 nm of the field, and for each one
checks four things against each of the six runway ends:README 전문 보기 ↗A single-purpose site for plane spotters at Ben Gurion Airport (TLV/LLBG): it works out which runways are actually being used for landings and takeoffs at this moment, and tells you where to stand.
No build step, no backend. Open index.html or serve the folder statically.
No free source publishes TLV's runway configuration — ATIS on 132.500 is voice only — so the app derives it from live traffic.
Every 20 seconds it pulls all aircraft within 20 nm of the field, and for each one checks four things against each of the six runway ends:
data/airport.json carries the local magnetic variation)Low, aligned, on the approach side, descending → landing on that runway. Climbing away past the far end → departing from it. High overflights and taxiing aircraft drop out.
Each aircraft then casts one vote, so a single aircraft in a hold cannot outvote a stream of real traffic. Votes decay with an 8-minute half-life and expire after 20 minutes, which is what lets the reading follow a genuine configuration change instead of averaging across it. Confidence combines how dominant the winning runway is against how much traffic we have actually seen — thin traffic reads as low confidence rather than as a confident guess.
Fallback. When traffic is too thin to read (quiet hours, or every source down), the
app falls back to the published time-of-day pattern and labels it predicted from time of day in amber. It never presents a guess as an observation.
The original idea was to read runway usage off FR24. Two problems:
So the app reads the same underlying ADS-B signal directly from community networks that are keyless and free for non-commercial use, tried in order so one being down is not an outage:
adsb.lol → adsb.fi → airplanes.live
That order is empirical: a CI run against the deployed proxy showed airplanes.live failing and adsb.lol answering, so airplanes.live appears to refuse requests from Cloudflare's datacenter IPs and is tried last.
None of these networks sends an Access-Control-Allow-Origin header, so a browser
will not let the page read their responses, however reachable they are. This was
confirmed from a real phone against the deployed site: all six endpoints answered a
no-cors probe in 45-128 ms while every normal request failed - reachable, but blocked
by policy. No client-side change can work around that.
api/adsb.js is a Vercel serverless function that sits in front of them, adds the CORS
header, and lets Vercel's CDN cache each distinct query. The cache matters beyond
latency: s-maxage=45 means a hundred spotters using the site produce one upstream
request every 45 seconds rather than a hundred polls, which is what these volunteer-run
networks ask for. stale-while-revalidate=900 keeps the last good response serving for
fifteen minutes if the upstreams stop answering.
Requests are clamped to a bounding box around Israel and to 50 nm so it cannot be used as a general-purpose ADS-B proxy.
Not the Edge runtime. Vercel's Edge Functions run on Cloudflare's network, and these upstreams refuse it. The first version of this proxy was a Cloudflare Worker, and it got:
airplanes.live: HTTP 403 adsb.lol: HTTP 429 adsb.fi: HTTP 403
A CI step then called the same endpoints from a GitHub runner and got 200 from both
adsb.lol and adsb.fi seconds later. So the refusal is aimed at Cloudflare's shared
egress IPs, not at datacenter traffic generally - Workers share those IPs across
thousands of customers, and the rate limit applies to a pool this site cannot influence.
The Node runtime runs on AWS and is not caught by it.
airplanes.live returns 403 from everywhere with "Please contact us at [email protected]", which is an access request rather than a block. It stays last
in the upstream list until that access is granted.
worker/adsb-proxy.js is kept as a second deployment target. The block is on
Cloudflare's IP reputation rather than on anything the code does, so it may become
usable again. Both import their shared logic from shared/adsb-core.js, so the upstream
list and validation cannot drift apart.
Free, no card, a couple of minutes.
api/adsb.js as a serverless function on its own.data/config.json as adsbProxy - that is the
deployment URL with /api/adsb on the end, e.g.
https://spotil.vercel.app/api/adsb. The client appends only the query string, so
the same field works for either proxy without host-specific path building.Check it with https://<your-site>/debug.html, which tests the configured proxy
alongside the direct endpoints.
Leaving adsbProxy empty is valid - the site then falls back to the time-of-day
prediction and says so, rather than breaking.
data/spots.json is the local knowledge, and it is the part most worth improving.
The primary source is Moti Kaplan's post in the Facebook group חובבי הספוטינג בישראל (30 Aug 2025), which pairs spots to runways and to time of day:
| When | Landing | Spot |
|---|---|---|
| Morning | 12 (west→east) | Arcafe Or Yehuda, in the car park |
| Late morning–afternoon | 21 (from the north-east) | Bnei Atarot junction / Big Yehud |
| Evening | 30 (from the east) | Airport City / Dor Alon TLV |
| Most of the time | takeoffs from 26 | Western operations area, the old "Bama" spot |
Runway 08 (the reciprocal of 26, used on easterly winds and often at night) and the Route 461 / Hatayasim option come from public spotting guides and are marked as such.
Coordinates are best-effort estimates and every spot carrying one is flagged
coordsApproximate: true. The Navigate buttons therefore search by place name, not
by coordinate, so they route correctly even where a pin is off by a few hundred metres.
Fixing a pin is a one-line edit to data/spots.json — the map and the distance readout
pick it up on reload.
Runways with no spot on file yet are listed under uncovered in the same file.
index.html markup and page shell
assets/style.css styling, light and dark
js/geo.js bearings, distances, cross/along-track maths
js/sun.js solar position and light quality
js/adsb.js live aircraft, via the proxy with direct fallback
js/runway.js runway-in-use detection and vote tracking
js/recommend.js runway → ranked spots
js/i18n.js EN/HE strings
js/app.js UI wiring
data/airport.json runway geometry, magnetic variation, time-of-day pattern
data/spots.json spotting locations
data/config.json proxy URL
debug.html data source diagnostics
shared/adsb-core.js upstream list, validation and fetching, shared by both proxies
api/adsb.js the Vercel proxy (the live one)
worker/ the Cloudflare Worker proxy (blocked by upstreams; kept as a spare)
python3 -m http.server 8777 # then open http://localhost:8777
The modules are plain ES modules, so it must be served over HTTP, not opened as a
file:// URL.