C.E.O. Bee
Gömülü Sistemler ve IoT

Kimse Gelmeyecek: Çıplak PCB'den Gerçek Zamanlı Analitiğe 41.000 Özel Enerji Ölçüm Noktası

C.E.O. Bee Mühendislik16 dk okuma

Bir dağıtım şirketinin, enerjili şalt hücrelerinin içine monte edilmiş 41.000 devreden sekiz yıllık pil ömrüyle ve bir daha sahaya çıkma imkânı olmadan 15 dakikalık enerji verisi toplaması gerekiyordu. Hazır modemler hem fizik hem ekonomi testini geçemedi; biz de donanımı ve üzerindeki her katmanı kendimiz tasarladık.

Bir orta gerilim şalt odasında, çelik bir kapının arkasında, tasarladığımız bir kart enerji darbelerini donanım sayacına işlerken mikrodenetleyicisi 2,6 µA'de uyuyor. İşletmenin bölgesinde bunlardan 41.318 adet var; hepsi enerjili hücrelerin içine ya da yanına monte edilmiş durumda.

İlk tasarım toplantısında yazdığımız ve proje boyunca hiç gevşetemediğimiz varsayım şuydu: hiçbir teknisyen bir daha bu kartların hiçbirine dokunmayacak. Aşağıdaki her şey bu tek cümlenin sonucu. Layout disiplini, kulomb defteri, bootloader'ın connectivity watchdog'u, ingestion hattını sonunda ikiye bölmemiz; hepsi. Kimse gelmeyecekse bir hata artık bir "ticket" değildir; bir saha çıkışıdır ya da ölü bir uç noktadır. Kırk bir bin kez.

Satın almak yerine üretmek: kararın ve faturasının anatomisi

Müşteri, ağır sanayi müşteri portföyü olan bir dağıtım şirketi. İstedikleri tek cümleye sığıyordu: fider ve büyük müşteri devresi çözünürlüğünde, uzlaştırma periyoduyla hizalı 15 dakikalık enerji verisi; her yerde ve kalıcı olarak. Bariz yol ticari bir hücresel sayaç modemiydi ve bu yolu ciddiye alıp dört farklı ürünü değerlendirdik, sonra birbirinden bağımsız iki gerekçeyle kapattık. Birbirinden bağımsız iki gerekçe rahat bir yerdir; çünkü tartışma sıkışsa bile ikisinden birinin ayakta kalması yeter.

Önce ekonomi. Modül, muhafaza ve anten için uç nokta başına 118 €, üstüne SIM başına aylık 1,85 €: 41.000 uç noktada, %18 yenileme oranıyla birlikte on yıllık program 15,9 M€ çıkıyordu. Özel donanım yolu 4,2 M€ oldu: dört kart revizyonu, EMC laboratuvarı ve kalıp dahil 1,4 M€ NRE, hacimde 37,40 € kart maliyeti, kurulu hâliyle 2.450 €'dan 287 özel LoRaWAN gateway'i ve on yıllık ağ ile backend operasyonu. 11,7 M€'luk bir farkı sonradan mühendislikle kapatamazsınız. O sayı, programın var olup olmaması demektir.

Fizik bu kararı zaten tek başına veriyordu, ama bunu rahatça söyleyebilmemiz on dört ay sürdü. Temsili 40 kabine o kadar süreyle sıcaklık ve RF logger'ı bıraktık. Kabin içi sıcaklık −22 °C ile +71 °C arasında değişti; ağustosta güneye bakan bir beton köşk muhafazasında +78 °C zirve gördük. Değerlendirdiğimiz modemlerin çalışma aralığı ise 0–55 °C idi. Daha kötüsü, topraklanmış çelik bir hücre epeyce iyi bir Faraday kafesidir. Kapının kapanması 19–31 dB'ye mal oldu ve 40 sahanın 22'sinde kapalı kapı ile ölçülen LTE RSRP değeri −103 ile −117 dBm arasındaydı. Burası modemin oturumu çökene kadar tuttuğu bölgedir ve her yeniden bağlanmanın bedeli pilden ödenir. 868 MHz'de, kabin dışına çıkarılmış bir anten ve LoRa'nın link bütçesiyle aynı kayıp, üstüne marj bile bırakarak soğurulabiliyor.

Özel donanımı seçmek, saf yazılım ekiplerinin hiç karşılaşmadığı arıza modlarını sahiplenmeyi seçmektir: nem girişi, lehim yorulması, silikon errata'sı, "hayır" diyen bir EMC laboratuvarı, bir öncekinden farklı sıcaklık katsayısına sahip bir direnç makarası. Bunu bilerek girdik. Yine de bizi şaşırttı.

Size karşı çalışan bir hücrenin içine tasarlamak

Uç nokta dört katmanlı bir kart. Üzerinde bir STM32L451CE var (Cortex-M4F, 512 KB flash); geliştirme hızı için Arduino framework'ü ile derliyoruz ve bugün yeniden başlasak yine aynısını yapardık. Düşük güç, DMA ve metroloji yolları ise mikroamperin ve çevrimin gerçekten önem taşıdığı yerlerde LL katmanına indirildi. Ölçüm ön ucu çok fazlı ADE7880, telsiz ise EU868'de SX1262, LoRaWAN 1.0.4 Class A.

Kolay kısmı bu. Zor kısmı kartın etrafında olup bitenler. Bir hücrede vakum kesici manevrası, kV/µs mertebesinde dV/dt'ye ve 100 kHz'den 100 MHz'in çok ötesine yayılan ışıma enerjisine sahip ön-ark ve yeniden ateşleme darbeleri üretir. IEEE 1613 / IEC 61850-3 zarfını hedefleyerek tasarladık; IEC 61000-4-2, -4-4, -4-5, -4-6 ve buradaki asıl kritik test olan -4-18 sönümlü salınımlı dalga testlerini uyguladık.

Yükün büyük kısmını layout taşıdı. Analog ve dijital bölümler arasında ground plane'i bilerek bölmedik; klasik "ground split", bir referans düzlemini slot antene çevirmenin en etkili yollarından biridir. L2'de kesintisiz tek düzlem, üstteki komponent yerleşimiyle kontrol edilen dönüş akımı geometrisi, küçük tutulup ölçüm zincirinden uzaklaştırılan bir boost dönüştürücü sıcak döngüsü; RF bölümü kendi shield can'i içinde, coplanar waveguide beslemeli ve can duvarını ya da muhafaza rakorunu geçen her iletkende pi filtre besleme geçişleriyle. Akım trafosu sekonderleri burgulu çift üzerinden, ortak mod bobini ve çift yönlü TVS'in ardından, modülatör bandının epey altında bir RC anti-alias köşesine giriyor.

Bunların hiçbiri ilk laboratuvar ziyaretinde IEC 61000-4-4'ü ±2 kV'ta geçmemize yetmedi. İki sebep vardı ve ikisini de ben onaylamıştım: AFE'nin SPI chip-select hattı 40 mm boyunca hasat dönüştürücüsünün anahtarlama düğümüne paralel gidiyordu ve rakor, ortak mod akımının ölçüm çiftine binmesine izin veriyordu. O yönlendirmeyi iki kez gözden geçirmiş, iki kezinde de üstünden okuyup geçmiştim. Görebilmem için bir burst jeneratörü ve elimde kalmış bir test raporu gerekti. Guard trace ile yeniden yönlendirme, ortak mod bobini, sıcak döngünün taşınması: ±4 kV'ta geçtik. Ama gerçek bir hücrede bunun %100'ünü asla filtreleyemezsiniz; bu yüzden firmware bozulmayı varsayarak çalışır:

  • Her ADE7880 register işlemi, SPI çerçevesi üzerinde bir CRC ile sarmalanır; bu, özellikle veri yolu bozulmasını yakalar.
  • AFE'nin kendi CHECKSUM register'ı, yani konfigürasyon register haritası üzerindeki CRC, her 64 birikim penceresinde bir okunur. Asıl tehlikeli arızayı bu yakalar: bir EMI olayının sessizce bir kazanç register bitini çevirmesi ve cihazın ondan sonra sonsuza kadar makul görünen ama yanlış veri üretmesi.
  • Raporlanan RMS ve güç faktörü değerleri, 200 ms'lik yedi hat-çevrimi penceresinin medyanıdır; pencereler aşırı aralık, PLL kilit kaybı veya fazla ikinci-fark enerjisi durumunda reddedilir. Sonuncusu bir checksum değil, darbe gürültüsü dedektörüdür; çünkü analog bozulma aritmetik olarak geçerlidir ve hiçbir checksum ona itiraz etmez.
  • Enerjinin kendisi donanım darbe sayımından gelir ve fiziksel bir makuliyet sınırıyla kuşatılır: Imax'ta mümkün olan maksimum CF frekansını biliriz, dolayısıyla bunun üzerindeki her sayım tanım gereği gürültüdür. Ayrıca darbe kaynaklı enerji, her periyotta register birikimleriyle %0,5 tolerans içinde çapraz kontrol edilir.

Telsiz backoff'u da aynı bozucuya göre ayarlandı. Uplink kaybı kesici manevralarıyla güçlü korelasyon gösteriyordu ve saf bir "hemen tekrar dene" mantığı sizi doğrudan aynı darbe zarfının içine geri düşürüyor. Bu yüzden ilk tekrar 3–11 s rastgele gecikmeyle, sonrası tam jitter'lı üstel artışla yapılıyor; metroloji bloğu bir geçici olay bayrağı kaldırdığında verici 400 ms boyunca tamamen bastırılıyor. Fırtınanın içine yayın yapmayın.

Tek bir A-boy pilde sekiz yıl

3,06 Ah kullanılabilir kapasiteye karşı sekiz yıl, ortalama 43 µA akım bütçesi demek. Bu bölümdeki her şey o tek sayıdan türüyor ve devam etmeden önce bu bütçenin ne kadar az şey satın aldığını bir hissetmekte fayda var.

Hücre bir Saft LS 17500: A boy lityum tionil klorür, 3,6 Ah. Yanına, verici darbesini besleyen bir hibrit katman kondansatörü koyduk; çünkü Li-SOCl₂ hücrelerin iç empedansı yüksektir ve 45 mA'lik bir darbede gerilim çöker.

Buradaki asıl mimari hamle, pilin ölçümün bedelini büyük ölçüde hiç ödememesi. Enerji bir integraldir; her on beş dakikada 200 ms örnekleyip gerisini ortalamaya bırakarak kWh hesaplayamazsınız. Bu yüzden ADE7880 sürekli olarak ayrı bir hasat akım trafosundan besleniyor. Bu trafo yaklaşık 35 A primer akımın üzerinde 90 mW'ın fazlasını veriyor ki bu da fider-saatlerinin yaklaşık %91'ini kapsıyor; CF1 darbe çıkışı ise MCU STOP2'de uyurken bir LPTIM sayacını sürüyor. On beş dakikada bir uyanmak bir ölçüm oturumu değil, bir sayaç okuması. Hasat eşiğinin altında yük zaten küçük; düşük çözünürlükte duty cycle'lı pil ölçümü savunulabilir ve Class 1'in hata zarfı 0,05 Ib altında zaten genişler.

Ölçülen uyku akımı 25 °C'de 1,4 µA, 70 °C'de 6,8 µA idi. Veri sayfası tipik değerleri 25 °C'de verilir; kabinler 25 °C değildir. Logger verisiyle sıcaklık ağırlıklandırıldığında uyku yıllık 2,6 µA'ya oturuyordu ve toplam model 43 µA tavana karşı 31 µA çıkıyordu. Rahat. Ağ ortadan kaybolana kadar da öyle sandık.

Sonra bir fiber kesintisi ve yanlış yapılandırılmış bir LTE yedek APN'i 63 gateway'i 31 saat boyunca devre dışı bıraktı; 11.400 cihaz ağı kaybetti. LoRaWAN'ın ADR geri çekilmesi tam olarak standardın söylediğini yaptı: ADR_ACK_LIMIT kadar downlink'siz uplink'ten sonra cihaz ADRACKReq kurar, ADR_ACK_DELAY kadar sonra maksimum güce çıkar, ardından veri hızını SF12'ye doğru indirir. Uplink başına enerji 2,3 µAh'ten yaklaşık 19 µAh'e çıktı; bunu teyitli uplink tekrarlarıyla çarpın ve bir buçuk gün boyunca çalıştırın.

Bunu kimse anlık olarak görmedi. Yayın yapamayan bir cihazın telemetrisini gözleyemezsiniz ve tionil klorür hücrelerin deşarj eğrisi o kadar düzdür ki, hücre bitmek üzere olana kadar terminal gerilimi size hiçbir şey söylemez. Bize sonradan söyleyen şey firmware'in kulomb defteri oldu: üretimde ölçülen cihaza özel TX akımını ve sıcaklık telafili kaçak eğrisini kullanarak işlem başına modellenen enerjiyi entegre eden, NVM'de tutulan ve her uplink'te raporlanan bir birikim sayacı. Filo geri döndüğünde defter, 31 saatte toplam bütçenin %4,1'inin harcandığını gösterdi.

O sorguyu üç kez çalıştırdım, her seferinde sorguyu yanlış yazmış olmayı umarak. 3,9 aylık tasarım ömrü bir buçuk günde gitmişti ve olurken bakabileceğimiz hiçbir şey yoktu. Yılda altı böyle olay, programı sekiz yıldan üç yılın altına indirirdi.

Ağa ulaşamayan bir cihaz, ulaşmaya çalışırken kendini sessizce ölüme harcar. Pille çalışan bir filoda akılda tutulacak cümle şu: bağlantı kesintisi aslında bir enerji kesintisidir, faturası sonra gelir.

Çözüm, uygulama katmanının üstünde yetkiye sahip bir enerji yöneticisi oldu.

// Her yayın kararından önce çalışır.
typedef enum { LINK_NOMINAL, LINK_DEGRADED, LINK_ISLANDED } link_state_t;

static bool tx_permitted(sched_ctx_t *ctx) {
    // 1. Sert 24 saatlik kota; zamanlayıcıya değil kulomb defterine karşı.
    if (ledger_spent_since(ctx->day_epoch) +
        tx_cost_estimate(ctx->dr, ctx->len) > ctx->day_quota_nah)
        return false;                    // uygulama katmaninin oy hakki yok

    // 2. Anahtarlama transientinin icine asla yayin yapma.
    if (metro_transient_age_ms() < 400) return false;

    switch (ctx->link) {
    case LINK_NOMINAL:
        return true;
    case LINK_DEGRADED:                  // >32 uplink, sifir downlink
        ctx->confirmed = false;          // kimsenin gondermedigi ACK'e para odeme
        ctx->dr = ctx->dr_last_known_good;   // MAC'in SF12'ye kaymasini reddet
        return true;
    case LINK_ISLANDED:                  // >6 saat sessizlik: sadece yoklama.
        // AFE integre etmeyi hic birakmadi; tam cozunurluklu veri ring
        // buffer'a dusmeye devam ediyor. Yoklama 60 s -> 30 dk, jitter'li.
        return ctx->now >= ctx->next_probe_at;
    }
}

Referans MAC davranışından sapmak, sessizce yapılacak bir şey değil; yazıp bir tasarım gözden geçirmesinde savunacağınız bir karardır. Burada savunulabilir olmasının nedeni, işletmenin kendi ChirpStack ağ sunucusunu çalıştırması ve hattın iki ucunun da bizde olması. Sunucu tarafında artık gateway kümesi sessizliği 90 saniye içinde alarm üretiyor. 34 ay ve sonraki dört kesinti boyunca defter, 8 yıllık hedefe karşı filo medyanını 9,2 yıl, 5. persentili 7,6 yıl olarak öngörüyor.

Kırk bir bin ayrı kalibre edilmiş ölçüm cihazı

Bu bir tarifeye esas sayaç değil ve tip onayı peşine düşmedik. Ama işletme verilerimizi trafo merkezi sınırındaki sayaçlarla mutabakata sokuyor; yani bizim sayılarımız sürekli olarak başka birinin sayılarıyla karşılaştırılıyor. IEC 62053-21 Class 1 hata zarfını sert bir iç gereksinim olarak tutmamızın sebebi bu.

Bu bütçenin büyük kısmını tek bir terim yiyor ve aritmetik hiç affetmiyor. Güç faktörü 0,5'te, telafi edilmemiş 0,3°'lik bir akım trafosu faz kayması %0,91 enerji hatası üretiyor. Derecenin onda üçü. Kâğıt üstünde hiçbir şey gibi durur ve elinizdeki bütçenin neredeyse tamamını götürür; cihaz başına faz telafisinin burada opsiyonel değil zorunlu olmasının sebebi de tam olarak bu.

Üretimdeki asıl ödünleşme termaldi. Kart başına tam üç noktalı iklim kabini karakterizasyonu 41 dakikalık fikstür süresi demek; 41.000 adette bu bir test adımı değil, ikinci bir fabrika demek. Bunun yerine her kart için 25 °C'de, Class 0,05 referans kaynağa karşı beş noktalı kazanç, ofset ve faz kalibrasyonu yapıyoruz, kart başına 96 saniye. Buna ek olarak komponent lotu başına %5'lik örneklemde tam −25/+25/+70 °C karakterizasyonu uyguluyoruz; çünkü aynı makaradan gelen AFE'ler ve şöntler birlikte kayar. Her cihazın katsayı seti, kendi kazançlarının kendi lotunun ikinci dereceden termal polinomuyla bileşimi. Saha sonucu: −25 °C'de 95. persentil hata %0,61.

Katsayılar, DevEUI ve kök anahtar korumalı bir flash sayfasına yazılıp fabrika HSM'i tarafından imzalanıyor; aynı kayıt kart seri numarası, AFE lotu ve akım trafosu seri numarasıyla anahtarlanmış bir provizyon veritabanına da düşüyor. Her cihaz açılış uplink'inde kalibrasyon kaydının hash'ini raporluyor. Bu kontrol daha tek bir sevkiyat yapmadan kendini ödedi: bir ICT fikstür hatası 64 kartlık bir tepsiyi kaymalı bir seri eşlemesiyle yazdı ve 64 cihaz komşusunun faz telafisiyle hattan çıktı. Hash uyuşmazlığı 64'ünü de yakaladı.

Saha kayması ise hiçbir şeye dokunmadan, enerjinin korunumu üzerinden denetleniyor. Her trafo merkezinde alt uç noktaların toplamı, bara sayacından modellenen trafo kayıpları çıkarıldığında elde edilen değere eşit olmalı. Kalıntı üzerinde, ölçek hatasını tek tek uç noktalara atfeden özyinelemeli bir kestirimci çalıştırıyoruz. Ayırt edilebilirlik anahtarlama olaylarından geliyor: fider konfigürasyon değişiklikleri ve kesici manevraları karışım matrisini değiştirir ve korelasyonlu bir yük popülasyonu içinde tek tek cihazları ayrıştırılabilir kılan şey tam da budur. 26 ayda bu yöntem 214 cihaz işaretledi. 189'u tezgâhta tolerans dışı ya da kaymaya başlamış olarak doğrulandı, 25'i yanlış pozitifti. 400 cihazlık rastgele bir denetimde ise kestirimcinin kaçırdığı tolerans dışı tek bir cihaz çıkmadı.

Veri sayfasında yazmayan trafik deseni

Kararlı durumda 41.000 cihaz, on beş dakikada bir uplink: saniyede 46 mesaj. Önemsiz. Kararlı durum aynı zamanda bu sistem hakkında en az şey söyleyen sayı.

O 63 gateway geri döndüğünde 11.400 cihazın her biri 124 periyoda kadar tamponlanmış veri tutuyordu ve duty cycle'ın izin verdiği hızda boşaltmaya başladı. Sürekli yazma hızı 118.000 satır/s zirve yaptı. Bu kısmı yalnızca bir ölçekleme problemiydi. Asıl problem şuydu: birikmiş kayıtlar 31 saate kadar eski zaman damgaları taşıyıp canlı veriyle iç içe geliyordu ve alt taraftaki hemen her bileşen sessizce "çoğunlukla ekleme, kabaca sıralı yazma" varsayıyordu. Kimse bu varsayımı bir yere yazmaz. Onu ancak ihlal ederek bulursunuz.

ClickHouse bunu bize mümkün olan en tanıdık biçimde söyledi: Too many parts. Merges are processing significantly slower than inserts. Geniş bir olay-zamanı aralığına yayılmış küçük ve sık insert'ler part patlaması üretir. Yazma yolunu, 30 saniye ya da 200 bin satırdan hangisi önce dolarsa ona göre biriktiren bir consumer ile düzelttik; (device_id, ts) sıralama anahtarı ve aylık partition ile birlikte tablo başına günlük part sayısı yaklaşık 1.900'den 96'ya düştü.

Daha ince hasar stream katmanındaydı. Flink işlerimiz cihaz bazında anahtarlanıyor ve pencereli durum tutuyor; replay'i karşılamak için izin verilen gecikmeyi 31 saate çıkarmak, pencerelerin hiç kapanmaması ve 41.000 anahtar üzerinde durumun sınırsız büyümesi demek. Bunu kurtaracak bir ayar parametresi yok, çünkü bu bir ayar problemi değil, modelleme hatası. Bu yüzden hattı doğrudan kaynağında böldük. Her kayıt live ya da replay şeklinde bir origin etiketi taşıyor; cihaz bunu zaten biliyor, çünkü kaydın ring buffer'dan gelip gelmediğini biliyor. Canlı kayıtlar 90 saniye izin verilen gecikmeyle düşük gecikmeli olay-zamanı yolundan gidiyor ve hiçbir zaman geç watermark görmüyor. Replay kayıtları ise depolamaya doğrudan yazan ve yalnızca etkilenen pencereleri hedefli biçimde yeniden hesaplatan ayrı bir yola gidiyor. Canlı watermark hiçbir zaman geçmişe rehin verilmiyor.

Backpressure'ın nihayetinde uç noktaya kadar ulaşması gerekiyor ve işin tuhaf tarafı, bir LoRaWAN ağında kıt kaynağın uplink değil downlink olması; gateway'ler yarı çift yönlü ve duty cycle ile sınırlı. 11.400 cihazı tek tek kısıtlamak, birikmiş verinin kendisinden daha fazla anten süresi harcardı. Bunun yerine boşaltma hızını, her cihazın yeniden bağlanırken zaten MAC durumu için almak zorunda olduğu ilk downlink'e iliştirdik. Sıfır ek anten süresi, filo geneli akış kontrolü. En kötü boşaltma boyunca canlı yol p99'u 1,4 s'de kaldı.

Sorun hacim değil, kardinalite

Depolama katmanını hacme göre boyutlandırdık; sonradan anlaşıldı ki endişelenmemiz gereken şey hacim değilmiş. Kırk bir bin seri, günde 96 nokta: günde dört milyondan az veri noktası, yani yuvarlama hatası. Asıl problem kardinaliteydi: her biri kendi referans davranışına ihtiyaç duyan 41.000 bağımsız, düşük hızlı zaman serisi.

Üç katmanda karar kıldık. Katman 1 her uç nokta için her noktada O(1) maliyetle çalışıyor: haftanın çeyrek saati bazında 672 kovadan oluşan toplamsal mevsimsel durum, her kovada bir EWMA ortalaması ve sağlam bir ölçek kestirimi, yaklaşık yirmi kayan nokta işlemiyle güncelleniyor. Cihaz başına 5,4 KB, filo genelinde 224 MB: bellekte sıcak tutulacak kadar küçük ve hangi uç noktanın izlenmeye değer olduğuna karar vermek zorunda kalmayacak kadar ucuz. Anomali skoru, kalıntının eşleşen kovaya karşı sağlam z-skoru.

Katman 2 hiç model gerektirmeyen dedektörleri ekliyor: yavaş kayma için kalıntı üzerinde CUSUM, değişim noktası tespiti, faz akımı dengesizliği, güç faktörü eğilimi ve sıcaklığa normalize edilmiş kayıp katsayısı. Katman 3 ise pahalı — hava durumu değişkenli gradient boosting tahmini, fider bazlı çok değişkenli modeller — ve yalnızca Katman 1 ya da 2'nin zaten terfi ettirdiği birkaç yüz uç nokta üzerinde çalışıyor. Hesaplama gücünü sürprizin olduğu yere harcayın.

Alarmlar depolamayı sorgulayarak değil stream içinde değerlendiriliyor; güncel durum dar bir anahtarlı tabloda maddileştiriliyor, böylece operatörün haritası tek bir 41.000 satırlık tarama oluyor. Cihazın yayınından operatör alarmına p95 4,1 s, p99 6,8 s; bunun yaklaşık bir saniyesi anten süresi ve ağ sunucusu. Uç nokta seviyesinden toplanan gün öncesi fider tahminleri %3,1 MAPE ile çalışıyor.

İki yakalama, katmanlamanın ne kazandırdığını iyi gösteriyor. Sıcaklığa normalize edilmiş kayıp kesişimi on bir haftada %4,6 tırmanan bir dağıtım trafosu, herhangi bir eşik alarmının tetiklenmesinden çok önce işaretlendi; termal görüntüleme 68 °C sıcak nokta üreten, bozulmakta olan bir AG buşing bağlantısı buldu. Planlı bir kesintide değiştirildi; işletmenin kendi tahminine göre aksi hâlde yaklaşık 1.900 aboneyi etkileyen plansız bir kesinti olacaktı. İkincisine inanmamız daha uzun sürdü. Bir fiderde baş uç ile alt toplam arasında %7,8 sapma göründü, ama yalnızca hafta içi 01:00–05:00 arasında ve periyot altı keskinlikte bir aç/kapa kenarıyla. Bu şekil teşhis koydurucudur: ölçüm hatası orantılıdır ve zamandan bağımsızdır; devreye alınıp çıkarılan bir bypass ise zamanda yerelleşmiş ve kenarı keskindir. Bypass'tı. 26 ayda sistem, geri kazanılan faturalanabilir enerji karşılığı yaklaşık 2,1 M€ değerinde 31 doğrulanmış kaçak kullanım vakası ve arızalanmadan önce değiştirilen 17 teçhizat üretti.

Geri alamayacağınız firmware'i sahaya göndermek

Bir daha gidemeyeceğiniz bir filoya multicast firmware kampanyası başlatmak, veri merkezinde yaptığım hiçbir deploy'a benzemiyor. Doksan saniyede geri alma diye bir şey yok, yarısında durdurma diye bir şey de yok. Bu bölümdeki her şey o anı katlanılabilir kılmak için var.

Flash haritası şöyle: 32 KB yazma korumalı bootloader, iki adet 224 KB uygulama slotu ve 32 KB provizyon/kalıcı durum alanı; üretimde RDP Level 2 kurulu. Bootloader, yeniden birleştirilmiş imajın SHA-256'sı üzerindeki Ed25519 imzasını korumalı bölgedeki kök anahtara karşı doğruluyor. İmzasız hiçbir şey asla çalışmıyor.

Dağıtım LoRaWAN FUOTA yığınıyla yapılıyor: TS003 saat senkronizasyonu, TS005 multicast kurulumu, TS004 parçalı veri bloğu taşıması. Tam imaj 118 KB; bir önceki sürüme karşı ikili delta 11,8 KB, yani 48 baytlık 252 fragman. Üstüne yaklaşık %15 ek yük getiren 38 yedeklilik fragmanı gönderiyoruz; böylece herhangi 38 fragmanı kaçıran bir cihaz imajı sıfır yeniden iletim talebiyle geri kuruyor. Bu son derece kritik, çünkü downlink'i kıt bir ağda cihaz başına NACK-ve-yeniden-gönder ölçeklenmez. Kampanya sırasında cihazlar sınırlı bir pencere boyunca Class C'ye geçiyor ve bu ancak hasat akım trafosu onları beslediği için karşılanabiliyor; dolayısıyla kampanyalar fiderin yüklü olduğu pencerelere planlanıyor, hasat eşiğinin altındaki cihazlar güncellemeyi bir sonraki kampanyaya erteliyor. Unicast ile altı hafta sürecek bir filo çapında dağıtım, dört günlük multicast oturumlarında tamamlanıyor; buna rağmen bunu bilerek üç haftalık canary kapılarına yayıyoruz.

Derken v2.4.0, LoRaWAN kalıcı bağlamını yeni bir aşınma dengelemeli anahtar-değer deposuna taşıdı ve commit yolu yalnızca temiz kapanışta flush ediyordu. Sahada temiz kapanış diye bir şey yoktur. Soğuk açılan bir cihaz daha önce kullandığı bir DevNonce ile yeniden katılmaya çalışıyor, ağ sunucusu standarda uygun biçimde bu tekrarı reddediyor, cihaz da sonsuza kadar join deneyip hiç JoinAccept almadan bütçesini tüketiyor ve bir daha geri dönmüyordu. Yıkıcı ve tamamen sessiz.

Canary %0,5'ti, yani 206 cihaz; 72 saat soak ettik. Hiçbir şey çıkmadı, çünkü normal işletmede soğuk açılış esasen hiç olmuyor. Sonra planlı bir trafo merkezi kesintisi 41 canary cihazını soğuk başlattı ve 38'i sustu. Deneme açılış bayrağı onları kurtarmadı, çünkü firmware kusursuz çalışıyordu. Onları kurtaran şey bootloader'ın connectivity watchdog'u oldu.

slot_t choose_slot(void) {
    slot_t s = nvm->active;

    if (!ed25519_verify(nvm->sig[s], sha256(slot_image(s)), ROOT_PUBKEY))
        return other(s);                  // imzasiz imaj asla calistirilmaz

    if (nvm->trial[s] && nvm->boot_count[s] > 3)
        return revert(s);                 // klasik A/B: zaten calismiyor

    // Uygulama, ag sunucusu bizi hala duydugunu kanitladikca
    // last_downlink_utc damgasini gunceller. 26 saat > bir tam gunluk
    // dongu + olctugumuz en uzun mesru gateway kesintisi. v2.4.0'i
    // yakalayan kontrol budur: imaj kusursuz calisiyor, sadece ulasilamiyor.
    if (rtc_now() - nvm->last_downlink_utc > HOURS(26))
        return revert(s);

    return s;
}

38 cihazın tamamı v2.4.0'dan v2.3.6'ya döndü ve dört saat içinde ağa yeniden katıldı; o sürümün nonce deposu yayından önce, doğru sırayla commit ediyor. Join loglarında teker teker geri gelişlerini izledim, hepsini tek tek saydım ve o projede rahatlamaya en yakın hissettiğim an oydu. Ölçülen filo soğuk açılış oranı ayda yaklaşık %0,7; yani tam dağıtımda bu hata ilk yılında kabaca 3.400 cihazı kalıcı olarak susturacak, kaybedilen veri hariç yalnızca saha çıkışlarında yaklaşık 620 bin €'ya mal olacaktı. Canary kapısı artık zorunlu bir reset yoklaması içeriyor: altıncı saatte gönderilen bir downlink, canary cihazlarının %20'sini bilerek watchdog reset'ine sokuyor. Böylece yeniden açılış yolu yalnızca tezgâhta değil sahada da sınanıyor.

A/B şeması sizi çöken firmware'den korur. Kusursuz çalışıp sessizce ulaşılamaz hâle gelen firmware için hiçbir şey yapmaz ve filonun tamamını götüren de odur. "İmaj açılıyor mu" diye sormayı bırakıp "cihaz geri nasıl dönüyor" diye sormak lazım.

Otuz dört ayın sahada ürettiği sonuç

41.318 uç nokta canlı; 400 cihazlık bir pilotla başladı, 14 aylık kademeli bir dağıtımla buraya geldi. Pil telemetrisi, 8 yıllık tasarım hedefine karşı filo medyanını 9,2 yıl, 5. persentili 7,6 yıl olarak öngörüyor; enerji yöneticisi de eskiden tanesi aylarca ömre mal olan kesintileri artık soğuruyor. Doğruluk Class 1 zarfının içinde tutuluyor, kayma istatistiksel olarak yakalanıyor ve zaten planlanmış bakım pencerelerinde gideriliyor. Operatörler bir anomaliyi, cihaz yayınladıktan 4,1 saniye sonra görüyor. Program, kabinlerde zaten hayatta kalamayacak olan modem tabanlı alternatiften on yılda 11,7 M€ daha ucuza mal oldu.

Bunların hiçbiri zekice bir algoritmadan gelmedi. Erkenden şunu kabul etmekten geldi: zor kısıtlar fiziksel ve geri döndürülemezdi. 71 °C'deki çelik bir kutu, 43 µA'lik bir bütçe, saniyede yüzlerce milisaniyeyle ölçülen bir downlink kanalı ve bir daha asla dokunamayacağınız bir cihaz. Gerisi, metalin üstündeki her katmanın, stream işlemcisine kadar, bu kısıtlar tarafından şekillendirilmesine izin vermekti.