10.13. Tetiklenen çerçevelerin buluta yüklenmesi¶
Hareket tetiklendiğinde kamera artık panoyu canlandırıyor. Bu, canlı kullanım için yeterli, ancak sahibi aynı zamanda tetiklenen her çerçevenin kalıcı bir arşivini, kameranın dışında bir yerde saklanmış olarak istiyor. Bu, dışa giden bir HTTP çağrısıdır; kamera bir istemci olarak davranır.
10.13.1. İstemci olarak kamera¶
requests modülü, kameranın dışa giden HTTP istemcisidir. Yüzeyi, CPython’un requests modülünün bilinçli bir kopyasıdır; aynı fiil adlı modül fonksiyonları, aynı files=, json=, headers=, auth= anahtar kelime argümanları. CPython’dan HTTP çağrıları yaptıysanız API’yi zaten biliyorsunuzdur:
import requests
import io
ARCHIVE_URL = 'https://api.backyard-cloud.com/frames'
ARCHIVE_TOKEN = load_archive_token()
async def archive_frame(jpeg, ts):
try:
r = requests.post(
ARCHIVE_URL,
files={'image': (
'frame-{}.jpg'.format(ts),
io.BytesIO(jpeg),
)},
headers={'Authorization': 'Bearer ' + ARCHIVE_TOKEN},
)
except OSError as e:
print('upload failed:', e)
return False
if r.status_code >= 400:
print('archive rejected:', r.status_code, r.reason)
return False
return True
requests.post() bir TCP bağlantısı açar, isteği gönderir ve status_code, reason, headers, content, json() ve tanıdık özelliklerin geri kalanına sahip bir Response döndürür.
files={...} bir multipart/form-data gövdesi oluşturur. Değer bir (filename, file-like) demetidir; requests.post() dosya benzeri nesneyi parçalar halinde okur, böylece tüm JPEG’in önce yeniden bir dizgeye arabelleğe alınması gerekmez. io.BytesIO, halihazırda bellekte bulunan JPEG baytlarını sarar, böylece dosya gibi okunan bir arayüz sunarlar.
headers={...} istek başlıkları olarak gönderilen düz bir sözlüktür; burada standart Authorization konumunda bir bearer token bulunur. Arşiv sağlayıcısı hangi token biçimini istediğini belgeler; örnek, en yaygın biçimdir.
10.13.2. Hareket dedektörüne bağlanması¶
Daha önce tanıtılan hareket dedektörü eş yordamı, zaten her yeni çerçevede çalışır ve change > state['threshold'] olduğunda tetiklenir. Yüklemeyi oraya ekleyin, ancak bunu bir arka plan görevi olarak tetikleyin; böylece yükleme devam ederken dedektör izlemeyi durdurmaz:
async def motion_detector():
global last_motion
prev = None
while True:
await new_frame.wait()
change = compute_change(prev, latest_jpeg)
if change > state['threshold']:
state['trigger_count'] += 1
ts = int(time.time())
last_motion = {'ts': ts,
'count': state['trigger_count'],
'change': change}
motion_event.set()
asyncio.create_task(archive_frame(latest_jpeg, ts))
prev = latest_jpeg
await asyncio.sleep_ms(50)
asyncio.create_task() yükleme eş yordamını zamanlar ve hemen geri döner. Dedektör çerçeveleri yakalamaya devam eder; yükleme onun yanında çalışır; kamera asla takılmaz.
10.13.3. Hata durumları¶
Ağ kodu başarısız olur. Kamera çevrimdışı olabilir, arşiv kapalı olabilir, bearer token süresi dolmuş olabilir. Yakalanmaya değer kategoriler:
OSError– TCP bağlantısı açılamadı veya aktarım ortasında kapatıldı. DNS hatası, rota yok, bağlantı sıfırlaması.requeststam olarak bu istisnayı oluşturur.status_code >= 400– sunucu isteği aldı ve reddetti. Süresi dolmuş bir token için 401, iptal edilmiş bir token için 403, çok büyük bir gövde için 413, arşivin sağlıksız olması durumunda 5xx.Sessiz zaman aşımı –
requestsvarsayılan bir soket zaman aşımı kullanır (birkaç saniye); bunun ötesindeerrno.ETIMEDOUTileOSErroroluşturur.
Gerçekten önemli bir arşiv için, reddedilen çerçeveleri /sdcard/pending/ dizinine kuyruğa alır ve daha yavaş bir döngüde yeniden denerdiniz; bu, gösterilenlerin üzerine, her durum için birkaç satır daha demektir.
10.13.4. requests modülünün yapmadıkları¶
MicroPython portu bilinçli olarak küçüktür. CPython requests modülünün yaptığı ancak bunun yapmadığı birkaç şey:
Bağlantı havuzlaması. Her çağrı yeni bir TCP bağlantısı açar.
Geçici hatalarda otomatik yeniden denemeler. Çağrıyı kendiniz sarmalayın.
Akışlı yanıtlar.
r.contenttamamen RAM’e okunur;stream=Trueeşdeğeri yoktur.Gzip ile sıkıştırılmış yanıtların otomatik açılması.
Accept-Encodingbaşlığını yalnızca sunucu bunun için yapılandırılmışsa açıkça ayarlayın.
Tam yöntem listesi ve kapsam içi/dışı olanlar için requests — HTTP istemcisi belgesine bakın.
HTTPS kutudan çıkar çıkmaz çalışır; URL şeması bunu yönlendirir ve varsayılan SSL bağlamı anında oluşturulur. Kameraya yüklediğiniz bir CA paketine karşı arşivin sertifikasını doğrulamak için Genel bir sunucunun doğrulanması (istemci olarak kamera) belgesinin istemci olarak bölümüne bakın.
Uygulama tamamen teslim edildi: canlı önizleme, hareket tespiti, oturum açmalı pano, HTTPS, CORS/CSRF, bulut arşivi.