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.