10.13. Laukaistujen kehysten lataaminen pilveen¶
Kun liike laukaisee, kamera sytyttää nyt kojelaudan. Se riittää reaaliaikaiseen käyttöön, mutta omistaja haluaa myös pysyvän arkiston jokaisesta laukaistusta kehyksestä, tallennettuna jonnekin kameran ulkopuolelle. Tämä on lähtevä HTTP-kutsu – kamera toimii asiakkaana.
10.13.1. Kamera asiakkaana¶
requests-moduuli on kameran lähtevä HTTP-asiakas. Sen rajapinta on tarkoituksellinen kopio CPythonin requests-moduulista – samat verbinimiset moduulifunktiot, samat files=-, json=-, headers=- ja auth=-avainsana-argumentit. Jos olet tehnyt HTTP-kutsuja CPythonista, tunnet jo rajapinnan:
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() avaa TCP-yhteyden, lähettää pyynnön ja palauttaa Response-olion, jolla on status_code, reason, headers, content, json() ja loput tutuista ominaisuuksista.
files={...} rakentaa multipart/form-data-rungon. Arvo on (filename, file-like)-monikko; requests.post() lukee tiedostomaisen olion paloissa, jotta koko JPEG-kuvaa ei tarvitse ensin puskuroida uudelleen merkkijonoksi. io.BytesIO kietoo jo muistissa olevat JPEG-tavut niin, että ne tarjoavat tiedostona luettavan rajapinnan.
headers={...} on suora sanakirja, joka lähetetään pyynnön otsakkeina – tässä bearer-token vakiomuotoisessa Authorization-paikassa. Arkistopalvelun tarjoaja dokumentoi haluamansa token-muodon; esimerkki on yleisin muoto.
10.13.2. Kytkeminen liiketunnistimeen¶
Aiemmin esitelty liiketunnistimen korutiini suoritetaan jo jokaiselle uudelle kehykselle ja laukeaa, kun change > state['threshold']. Lisää lataus siihen, mutta laukaise se taustatehtävänä, jotta tunnistin ei lopeta tarkkailua latauksen ollessa käynnissä:
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() ajoittaa latauskorutiinin ja palaa välittömästi. Tunnistin jatkaa kehysten kaappaamista; lataus ajetaan sen rinnalla; kamera ei koskaan jumiudu.
10.13.3. Vikatilanteet¶
Verkkokoodi epäonnistuu. Kamera voi olla offline-tilassa, arkisto voi olla alhaalla, bearer-token voi olla vanhentunut. Kannattaa napata seuraavat luokat:
OSError– TCP-yhteyttä ei voitu avata tai se suljettiin kesken siirron. DNS-virhe, ei reittiä, yhteyden nollaus.requestsnostaa juuri tämän poikkeuksen.status_code >= 400– palvelin vastaanotti pyynnön ja hylkäsi sen. 401 vanhentuneelle tokenille, 403 peruutetulle, 413 liian suurelle rungolle, 5xx arkiston ollessa epäterveessä tilassa.Hiljainen aikakatkaisu –
requestskäyttää oletusarvoista sokettiaikakatkaisua (muutama sekunti); sen jälkeen se nostaaOSError-poikkeuksen arvollaerrno.ETIMEDOUT.
Arkistolle, jolla on todella merkitystä, jonottaisit hylätyt kehykset hakemistoon /sdcard/pending/ ja yrittäisit uudelleen hitaammassa silmukassa – se on muutama rivi lisää tapausta kohden näytetyn päälle.
10.13.4. Mitä requests ei tee¶
MicroPython-portti on tarkoituksella pieni. Muutama asia, jonka CPythonin requests tekee mutta tämä ei:
Yhteyksien poolaus. Jokainen kutsu avaa uuden TCP-yhteyden.
Automaattiset uudelleenyritykset ohimenevissä virheissä. Kääri kutsu itse.
Vastausten suoratoisto.
r.contentluetaan kokonaan RAM-muistiin;stream=True-vastinetta ei ole.Gzip-pakattujen vastausten automaattinen purku. Aseta
Accept-Encoding-otsake nimenomaisesti vain, jos palvelin on konfiguroitu sitä varten.
Katso requests — HTTP-asiakas täydellisen metodiluettelon sekä laajuuden sisä- ja ulkopuolelle jäävien asioiden osalta.
HTTPS toimii suoraan – URL-skeema ohjaa sitä, ja oletusarvoinen SSL-konteksti luodaan lennossa. Arkiston varmenteen tarkistamiseksi kameralle lataamaasi CA-pakettia vastaan katso Julkisen palvelimen varmentaminen (kamera asiakkaana)-sivun asiakkaana-osio.
Sovellus on täysin valmis: reaaliaikainen esikatselu, liiketunnistus, kojelauta kirjautumisella, HTTPS, CORS/CSRF, pilviarkisto.