2 puan yazan GN⁺ 2024-10-25 | 1 yorum | WhatsApp'ta paylaş
  • San Francisco’da arabasız yaşamda, evden çıkmadan önce yakındaki durağa bir sonraki varış saatini hemen gösteren bir cihaz daha kullanışlı
  • Eski bir Kindle jailbreak yapılarak duvara asılan bir e-mürekkep bilgi ekranına dönüştürüldü; ilk aşamada BART web sayfasının ekran görüntüsü düzenli olarak gösteriliyordu
  • MUNI de eklenince çok sayıda tarayıcı sekmesi, Raspberry Pi’de bellek yükü ve HTTP 429 bir araya gelerek ekran görüntüsü tabanlı yapının güvenilirliğini düşürdü
  • Rust ile yeniden yazılan sürüm, 511.org Stop Monitoring API üzerinden veri alıyor ve skia-safe ile Kindle çözünürlüğü ve 8-bit renk derinliğine uygun PNG’leri doğrudan üretiyor
  • Tarayıcı motoru kaldırılıp önbellekleme, hata gösterimi ve düzen ayarları da eklenince, günlük kullanım için uygun bir Kindle toplu taşıma ekranı ortaya çıktı

Evden çıkarken gereken bilgi basit

  • San Francisco’da arabasız yaşayan yazar, otobüs, tren, tramvay, troleybüs, cable car ve feribot gibi toplu taşıma araçlarını sık kullanıyor
  • CityMapper gibi uygulamalar bir yere giderken faydalı olsa da, evin önündeyken “nereye gidileceğinden” çok her hattın bir sonraki varış zamanı önemli
  • Hangi durağın ve hangi hattın kullanılacağı zaten biliniyorsa, genel amaçlı navigasyon uygulamalarının mevcut konum-hedef modeli gereğinden karmaşık kalıyor
  • Fikir, eski bir Kindle’ı akıllı ev ekranı olarak kullanan Matt Healy’nin yazısından ve eski bir Nook’u iCloud fotoğraf çerçevesine çeviren Ben Borgers’ın yazısından çıktı

Görüntüyü Kindle’da göstermeye kadar

  • İlk adım, Kindle’a jailbreak yapıp USBNet’i etkinleştirerek SSH erişimi açmaktı
    • Sonrasında cron göreviyle ekran düzenli aralıklarla yenilendi
    • mobileread wiki ve forumlarındaki Kindle hack kaynakları başvuru olarak kullanıldı
  • BART’ın Real Time Departure sayfası, istenen istasyon için sonraki trenleri ve otomatik yenilemeyi sunduğu için ilk veri kaynağı olarak uygundu
  • Kindle CLI içindeki eips ile PNG göstermeye çalışıldı ama başta görüntü aşırı esniyor veya kesiliyordu
  • Sorun, Kindle görüntüleme aracının 24-bit RGB PNG dosyalarını doğru işleyemeyip 8-bit görüntü gibi okumasıydı
    • ImageMagick convert komutunda -colorspace gray -depth 8 uygulanınca düzgün görüntülendi
    • Kindle ekran boyutuna uygun görüntü ve 8-bit renk derinliği temel koşullar oldu

İlk uygulama: Node.js, Puppeteer, Raspberry Pi

  • İlk sunucu, Node.js ve Puppeteer ile BART web sayfasının gereken bölümünü yakalıyordu
  • Yakalanan görüntü, Kindle ekran boyutuna ve 8-bit gri tonlamaya uygun biçime çevrildikten sonra HTTP endpoint’i üzerinden döndürülüyordu
  • Sunucu Raspberry Pi üzerinde çalışıyor, Kindle ise cron ile her dakika görüntüyü çekip eips ile gösteriyordu
  • BART sayfası zaten otomatik yenilemeyi desteklediği için, sunucu başlarken sayfa bir kez açık tutuluyor ve her istekte yeniden yüklenmiyordu
  • Bu sürüm bir süre iyi çalıştı ama bazen yenileme duruyor, bazen de sunucu bellek yetersizliği nedeniyle yeniden başlatılmak zorunda kalıyordu

MUNI genişlemesiyle ortaya çıkan sınırlar

  • San Francisco Bay Area’da 27 toplu taşıma işletmecisi var ve ilk uygulama yalnızca bölgesel hızlı tren sistemi BART’ı kapsıyordu
  • Daha sonra MUNI’nin otobüs ve hafif raylı durak varış saatlerini de birlikte görmek istendi
  • MUNI web sayfası da durak bazlı varış saatleri sunduğu için, önce birden fazla durak sayfasını Puppeteer ile yakalayıp ImageMagick ile birleştirme yöntemi denendi
  • Ekrandaki 7 bölümün her biri, Puppeteer’ın açık tutması gereken bir tarayıcı sekmesine karşılık geliyordu
    • Raspberry Pi’de yeterli bellek yoktu ve Chrome hafif değildi
    • MUNI sayfası sık istek aldığında HTTP 429 döndürüyordu
  • BART ve MUNI’yi birlikte gösteren ekran, yalnızca BART gösteren sürümden çok daha kararsızdı; tek bakışta bilgi veren bir ekran için daha güvenilir bir mimari gerekiyordu

Rust ile yeniden tasarlanan mimari

  • Yeniden yazılan sürümde Puppeteer çıkarıldı ve Rust HTTP sunucusu PNG’yi doğrudan üretir hale geldi
  • Dış arayüz Node.js sunucusuna benzer tutuldu ama iç uygulama tamamen değişti
  • Başlıca üç bileşen vardı
    • 511.org’dan sonraki varış saatlerini almak
    • Varış saatlerini 8-bit PNG görüntü olarak işlemek
    • Üretilen PNG’yi HTTP sunucusu üzerinden döndürmek
  • HTTP sunucusu için Axum kullanıldı
  • PNG çizimi için rust-skia kullanıldı
    • Skia, Chrome’un da temel grafik kütüphanesi olduğundan, Puppeteer’a göre daha düşük yükle aynı çizim teknolojisinden yararlanılabildi
  • Nihai sunucu kodu yaklaşık 1.200 satır tuttu ve yazıda önemli kısımlar özetlendi

511.org Stop Monitoring API’den veri alma

  • 511.org’un Stop Monitoring API, Bay Area durakları için tahmini varış-kalkış saatlerini XML ve JSON olarak sunuyor
  • Kullanılan endpoint biçimi http://api.511.org/transit/StopMonitoring/…] şeklindeydi
  • agency, Bay Area’daki 27 toplu taşıma işletmecisinden birini belirtir; SF MUNI için kod SF
  • API tek seferde yalnızca tek bir işletmecinin verisini getirebiliyor
    • Ya belirli bir durağın varış saatlerini ya da ilgili işletmecinin tüm durak verisini döndürüyor
    • Birden fazla durağın alt kümesini tek seferde çekmenin bir yolu bulunamadı
  • 511.org API sınırı saatte 60 istek olduğundan, durak başına ayrı ayrı çok sayıda istek atmak gerçek zamanlı ekran için uygun değildi
  • SF MUNI’nin tüm verisi istendiğinde HTTP isteği yaklaşık 5 saniye sürüyor, yaklaşık 27 MiB veri dönüyor ve biçimlendirilmiş JSON 1 milyon satırı aşıyordu
  • Tüm yanıtta yaklaşık 26k adet MonitoredStopVisit vardı ama ekranda aslında yalnızca belirli duraklar ve hatlar için LineRef, DirectionRef, DestinationName, StopPointRef, ExpectedArrivalTime, DestinationDisplay gerekiyordu

Rust ile veri işlerken karşılaşılan ayrıntılar

  • HTTP isteği, JSON ayrıştırma, zaman hesaplama, asenkron çalışma ve hata yönetimi için reqwest, serde, serde_json, chrono, tokio, eyre kullanıldı
  • MUNI durak kimlikleri SF MUNI sitesindeki durak sayfalarından bulunabiliyor
    • Örneğin Persia Ave & Paris St için inbound 15918, outbound 15919 olarak ayrı ID’ler var
    • MUNI durakları yön bazında ayrı ID kullanıyor
  • 511.org yanıtı JSON’un başına UTF-8 Byte Order Mark ekleyerek dönüyordu; doğrudan .json() ile ayrıştırılınca expected value at line 1 column 1 hatası çıkıyordu
  • Yanıt .text() ile UTF-8 metin olarak okununca BOM kaldırılıyor ve sonra serde_json::from_str ile ayrıştırılabiliyordu
  • Filtrelemeden sonra geriye yalnızca ilgilenilen duraklar için yaklaşık 20 varış bilgisi kaldı; bu da başlangıçtaki 26k kayda göre çok daha yönetilebilirdi
  • Veriler LineRef ve DirectionRef temelinde gruplanıp ExpectedArrivalTime’a göre sıralandı; UTC zaman damgaları da “kaç dakika sonra” biçimine çevrildi

Skia ile Kindle için PNG üretimi

  • PNG çizimi skia-safe ile kuruldu
  • Kindle ekran boyutu olan 1024x758 için Gray8 bitmap oluşturulup arka plan beyaza boyandı, ardından metin ve çizgiler çizildi
  • Önce yalnızca “Hello World” yazan bir PNG8 üretilerek çizim hattı doğrulandı
  • Daha sonra sahte varış verileriyle inbound ve outbound olmak üzere iki sütunlu tablo benzeri bir görüntü üretildi
  • Gerçek API verisi eklendiğinde, test verisine göre hedef ve varış süreleri daha çeşitli olduğu için sabit yerleşimde metin çakışmaları oluştu
  • Hızlı yineleme ve API sınırından kaçınmak için yanıtı data.json içinde önbelleğe alan geçici kod eklendi

Ekran düzenini iyileştirme

  • İlk gerçek veri ekranında, her satırdaki bilgi miktarı değiştiği için okunabilirlik düşüktü
  • Yapılan iyileştirmeler şunlardı
    • Varış sürelerini sağa hizalayarak tablonun sonundaki boşluğu azaltmak
    • Her sürenin sonundaki min ifadesini kaldırıp yalnızca listenin sonunda min göstermek
    • Yalnızca sonraki 3 aracı göstermek
    • Uzun hat adlarını hesaba katarak hedef adını daha sağa kaydırmak
  • Daha sonra hat ID’sini yuvarlatılmış gri konuşma balonu gibi göstermek için measure_str ile metin sınırları hesaplandı
  • Hedef metni, hat ID balonunun sağ ucundan 15 piksel uzağa yerleştirildi
  • Üste açık gri bir başlık eklenip Muni Inbound ve Muni Outbound ortalanarak gösterildi

PNG’yi Axum ile sunmak

  • HTTP sunucusu Axum 0.7 ile kuruldu ve /stops.png rotasında PNG döndürüldü
  • Yanıt başlığı Content-Type: image/png olarak ayarlandı
  • İlk olarak boş gövdeli bir HTTP 200 testi yapıldı, ardından görüntü üretim fonksiyonu bağlanarak PNG baytları doğrudan bellekten döndürülmeye başlandı
  • Kindle’da wget ile görüntü çekilip eips ile gösterildiğinde, başta görüntünün döndüğü ve kesildiği görüldü
  • Kindle varsayılan olarak dikey yön kullandığı için, yatay görünmesi adına çizimden önce döndürme matrisi uygulanması gerekti
    • Görüntü boyutu (758, 1024) olarak ters çevrildi
    • Tuval 90.0 derece döndürüldü

Gerçek kullanım sürümüne eklenen özellikler

  • Gerçek kullanım sürümüne şu özellikler eklendi
    • API verisini arka planda sürekli çekip HTTP sunucusunun hızlı yanıt vermesini sağlayan önbellek sistemi
    • Sol altta saat gösterimi ve sağ altta veri önbelleği durumu
    • Antialiasing
    • Varış saati alanıyla çakışmaması için hedef adını kısaltma işlemi
    • Hızlı ayırt edilebilmesi için hatlara göre farklı gri tonları kullanma
    • Yapılandırma dosyası tabanlı ayarlar
    • Hata olduğunda hatayı ve .source() zincirini PNG olarak çizip doğrudan Kindle’da gösterebilme
  • Birlikte hazırlanan sadeleştirilmiş sunucu kodu transit-kindle-simplified deposunda yer alıyor
  • Duvara asılı gerçek Kindle’ı çalıştıran sunucu kodu transit-kindle deposunda bulunuyor
  • BART ekran görüntüsü tabanlı sürüm yaklaşık Şubat 2023’te çalışıyordu; Rust ile yeniden yazılan sürümün son arayüz düzenlemeleri ise Ocak 2024’te tamamlandı

1 yorum

 
GN⁺ 2024-10-25
Hacker News yorumları
  • OneBusAway’in arkasındaki kâr amacı gütmeyen kuruluşta çalışıyorum. OneBusAway, her gün milyonlarca kişinin otobüs, tren, tramvay ve füniküler konumlarını ve varış saatlerini kontrol etmek için kullandığı açık kaynaklı bir proje.
    Şehrinizde zaten bir OneBusAway sunucusu varsa, yeni SDK ile özel uygulamalar geliştirebilirsiniz: https://github.com/onebusAway/?q=sdk&type=all&language=&sort...
    Sunucusu olmayan bir şehir için, bu yıl oluşturduğumuz Docker imajı ve OpenTofu yapılandırması ile GTFS/GTFS-RT beslemelerini REST API’ye dönüştürebilirsiniz.
    BART da GTFS ve GTFS-RT sağlıyor: https://mobilitydatabase.org/feeds/mdb-53
    ABD’deki diğer toplu taşıma kurumları da yeni federal kurallar nedeniyle en azından statik zaman çizelgesi verilerini GTFS olarak yayımlamak durumunda.
    İlgili yazılımlara katkı verecek geliştiricilere her zaman ihtiyaç var; özellikle de günde 250 bin kullanıcının deneyimini iyileştirmeye yardımcı olacak iOS geliştiricilerine çok ihtiyaç var. İletişim: aaron@onebusaway.org
    Docker: https://github.com/OneBusAway/onebusaway-docker / OpenTofu: https://github.com/OneBusAway/onebusaway-deployment

    • Şu anda dünya genelinde desteklenen şehir sayısı yalnızca 9 ve bunların 2’si beta; daha yaygınlaşırsa açık kaynak katkısı da kolaylaşacak gibi görünüyor.
      Süreç basit olursa kendi şehrimi de eklemek isterim. Son dönemde kütüphane ve SDK desteğine epey mühendislik zamanı harcanmış gibi görünüyor; ama yeni katkıcıların zaman ayırmasını kolaylaştıracak geliştirici deneyimi için kolay bir yola yatırım yapmak daha iyi olur gibi.
      Örneğin bu doküman oldukça karmaşık: https://github.com/OneBusAway/onebusaway/wiki/Multi-Region
    • OneBusAway’in dağıtıldığı şehirlerin listesini nerede bulacağımı merak ediyorum. “onebusaway cities” diye arayınca https://onebusaway.org/onebusaway-deployments/ çıkıyor, ama orada bahsedilen Adelaide gibi şehirler yoktu.
    • Açık kaynaklıysa neden yalnızca Play Store’da yer alıp F-Droid’de dağıtılmadığını merak ediyorum.
    • Sadece OneBusAway değil, Google Maps gibi otobüs takip uygulamalarının neden bu kadar hatalı olduğunu merak ediyorum.
      “4 dakika sonra varacak” yazıyor ama otobüs gözümün önünde ayrılıyor; ya da “5 dakika gecikmeli” denirken 2 dakika erken geliyor. Otobüsün hiç gelmediği de oluyor.
      Muhtemelen kaynak veri sorunudur, ama bu güvenilirliğin neden bu kadar düşük olduğuna dair içeriden bilgi edinmek isterim. Bu arada Seattle için konuşuyorum.
  • BART ve MUNI’nin ikisi de General Transit Feed Specification’ı destekliyor ve bu verileri almanın standart bir yolu var.
    https://gtfs.org/documentation/overview/#gtfs-realtime

    • Gerçek zamanlı bilginin ne kadar güvenilir olduğunu merak ediyorum. Google Maps “otobüs 4 dakika sonra varacak” diyor ama otobüsün uzaklaştığını görüyorum; ya da “5 dakika gecikmeli” derken gerçekte 2 dakika erken geldiği sık oluyor.
  • Gerçekten çok hoşuma gitti. Eskiden Boston’da arabasız yaşarken, A’dan B’ye gitmenin birden fazla yolu olduğu ve “en iyi” seçeneğin zamana ya da arada uğranacak yerlere göre değiştiği durumları yönetmek için çok daha kaba bir şeyi kendim bir araya getirmiştim.
    Örneğin işe gitmeden önce oğlumu okula bırakırdım ve bazen bırakıştan sonra kahvaltı ederdim. Sonraki kalkış saatlerini görmek, ilginç bir yerde 4 yaşındaki bir çocukla yürürken ortaya çıkan belirsiz durumlarda ya da kaçırınca sefer aralığı oluşacak bir trene yetişmek için acele edip etmemek gerektiği gibi kararları çok daha esnek vermeyi sağlardı.

  • https://oeffi.schildbach.de/index.html’ın henüz anılmamış olmasına şaşırdım. İstenen şeyi tam olarak yapıyor.

  • Birleşik Krallık’taysanız, istasyonlardaki kalkış panolarını taklit eden bir kalkış panosu cihazı satın alabiliyorsunuz
    https://ukdepartureboards.co.uk/store/product/desktop-depart...

  • Ben de SF’de yaşıyorum ve aynı sorunu çözmek için A Better Ride adlı bir iOS uygulaması yaptım
    Yalnızca çevredeki durakların toplu taşıma kalkış saatlerini gösteriyor. Amaç, toplu taşımayı öngörülebilir ve keşfetmesi kolay hâle getirerek stresi azaltmak. Para kazanma amacı olmadan, boş zamanlarımda yaptığım kişisel bir proje

    • Bu uygulama gerçekten harika. Yalnızca yakındaki hatları ve o hatların nereye gittiğini göstermesiyle diğer toplu taşıma uygulamalarından ayrılıyor
      Aktarma derdi olmadan gidebileceğiniz yerleri keşfetmenizi sağlıyor
    • Uygulama gerçekten çok iyi görünüyor. Canlı harita özellikle güzel
      Ben de bu alanda donanım geliştiriyorum ve son dönemde GTFS ile epey uğraştım; ulaşım verilerini ayrıştırıp göstermenin ne kadar çok iş gerektirdiği hemen belli oluyor
      Uygunsa, her duraktan yapılabilecek yolculukları özetleyip gruplama konusundaki UX kararlarınızı ve backend’i konuşmak isterim
    • Gerçekten iyi. Yolun hangi tarafı olduğu, genel gidiş yönünün nereye olduğu gibi pek çok özenli detay var
  • Kindle’ı jailbreak yapmanız ya da görüntü render etmeniz gerekmiyor
    Kendi yaptığınız web sayfasını Kindle tarayıcısında açıp, debug komutuyla Kindle’ın “ekran koruyucu” reklamlarını veya uyku ekranını kapatmanız yeterli
    Tarayıcı çubuğu Kindle’ın bir kenarında kalıyor ama cihazın yönünü çevirerek onu alta ya da sağa alabiliyorsunuz. Bunun karşılığında hava durumu·ulaşım·haber ekranını kolay HTML/CSS/JS ve istediğiniz backend diliyle yapıp, ucuz bir DigitalOcean 4 dolarlık instance gibi bir yerde çalıştırabilirsiniz
    https://blog.notfaqs.com/2018/06/kindle-e-reader-disable-scr...
    https://www.mobileread.com/forums/showthread.php?t=198334

    • Amazon’ın bu tür ekran hack’leri için Kindle tarayıcısında kiosk modunu teşvik edip eklemesi daha da harika olurdu
    • Android çalışan bir inkBOOK ile bunu denedim. Chrome APK’sını yükleyip kendi yaptığım web sayfasını açtım
      document.documentElement.requestFullscreen() ile gerçek tam ekrana geçiyor ve durum çubuğu da görünmüyor. Yerel toplu taşıma API’sine web sayfasından doğrudan erişilebildiği için backend’e de gerek kalmadı
      1. nesil Kindle ile baktım; sertifika geçersiz olduğu için HTTPS sitelerini neredeyse hiç kullanamıyor gibi görünüyor
        Yine de yerel ağdaki bir sunucuyla iletişim kuracak şekilde ayarlanırsa sorun olmayacağını düşünüyorum
    • Daha sonraki Kindle’larda ekran koruyucuyu devre dışı bırakma özelliğinin kaldırılmış olması neredeyse kesin
  • Bu kullanım senaryosunu pek anlamamış gibisiniz. “Trene binmek” istemiyorum; A’dan B’ye gitmek istiyorum
    Tren bozulduysa, grev varsa, hat 13.00-16.00 arasında kapalıysa ya da sefer saati değilse alternatif istiyorum. Bu yüzden benim ihtiyacım olan şey Google Maps’in verdiği, ya da vermeye çalıştığı şey
    Ferry Building’den Oakland’a gitmek istiyorsam ve BART arızalıysa feribot daha iyi olabilir; saat geçse taksi ya da Uber’dan başka seçenek kalmayabilir
    Tokyo’da Shibuya’dan Azabujuban’a gidiyorsam Ginza Line→Namboku Line, Hanzomon Line→Oedo Line, Yamanote Line→Namboku Line, 6 numaralı otobüs, taksi gibi seçenekler var
    Her hattın istasyonları ve otobüs durakları arasında da 3-8 dakika yürüme var; şu anda neye daha yakın olduğunuz seçimi etkiliyor. Geç kalıp kalmadığınız, bavulunuzun büyük ya da ağır olup olmadığı da önemli

    • Google Maps, yürümenin çok kötü bir şey olduğu ve kimsenin bunu istemediği yönünde güçlü bir varsayım yapıyor gibi
      Örneğin bir yere giderken 39 numaralı otobüse binip 15 dakika yürümek yeterliyken, Google’a sorduğunuzda 2 aktarmalı bir rota veriyor. Şanslıysanız tek otobüs+yürüme ile benzer sürede oluyor
      Bu yüzden 39 numaralı otobüsün ne zaman geleceğini bilmek istiyorsam hedefi bilerek farklı söylemem gerekiyor
      Ayrıca bulunduğum yerde Google’ın gerçek zamanlı verileri şüpheli; işletmecinin ya da bazı üçüncü tarafların verileri daha güvenilir
    • Kullanım senaryosu günlük ulaşım. Birçok insan çoğu zaman gerçekten “trene binmek” istiyor
      Gerçek zamanlı olarak çok gelişmiş plan yapmanız gereken durumlar da var ve böyle bir aracın olması güzel olur; ama günlük ulaşım çok daha basit araçlarla da yeterince karşılanabiliyor
      Verdiğiniz Tokyo örneği de ilginç, ama Google’a göre çoğu toplu taşıma seçeneği 30-40 dakika sürdüğü için kaba planlamada neredeyse eşdeğer. Taksi daha hızlı, bisiklet de neredeyse benzer
    • Her gün işe gidip gelirken gerçekten sadece “trene binmek” istiyorum
      Tren bozulmuşsa ya da grev varsa, bu gerçek zamanlı tren listesinde beklenmedik bir boşluk olarak ortaya çıkar
      Şehir içinde dolaşırken Google Maps’i açıp hedefi giriyorum, ama 500 kez gittiğim bir yere evden çıkarken özellikle açmıyorum
    • Tokyo merkezindeki toplu taşıma deneyimi tüm dünyaya genellenemez
      Bu, yalnızca Disneyland içindeki mağaza alışverişi ya da yemek deneyimini ölçüt almak kadar anlamsız. Sadece Suica’yı okutmak bile başka yerlere göre birkaç kat daha hızlı; zaten bazı yerlerde desteklenmiyor bile
    • https://citymapper.com hoşunuza gidebilir
      Çok özelliği var ama Tokyo’da ne kadar desteklendiğini bilmiyorum. Londra’da eve götürmesini istediğinizde maliyet, yürüme mesafesi, hız, aktarma, erişilebilirlik vb. kriterlere göre optimize edilmiş birden fazla yol gösteriyor
  • Yeniden değerlendirdiğim Lenovo ThinkSmart View tablet/toplantı odası cihazında Home Assistant ve yerel toplu taşıma kurumu entegrasyonunu ekleyerek benzer bir şey kullanıyorum
    Avantajı, kullanıma çok daha hazır olması. Elbette Lenovo’ya özel bir Android ROM yükledim, ama istediğim her şeyi gösterebiliyor; aydınlatma veya robot süpürge gibi şeyleri de kontrol edebiliyorum

  • BART haritasını fiziksel bir LED tabelaya dönüştüren güzel bir ürün de var: https://www.designrules.co/