time — idővel kapcsolatos függvények

A time modul függvényeket biztosít az aktuális idő és dátum lekérdezéséhez, időintervallumok méréséhez és késleltetésekhez.

Időkorszak (epoch): Az Alif- és i.MX RT-alapú OpenMV Cam-ek az 1970-01-01 00:00:00 UTC POSIX időkorszakot használják. Az STM32-alapú OpenMV Cam-ek a 2000-01-01 00:00:00 UTC időkorszakot használják. Az időkorszak éve futásidőben a gmtime(0)[0] segítségével határozható meg.

A tényleges naptári dátum/idő fenntartása: Ehhez valós idejű óra (RTC) szükséges. Az OpenMV Cam-en a rendszeridőt a machine.RTC objektum biztosítja. Az aktuális naptári idő a machine.RTC().datetime(tuple) segítségével állítható be, és fenntartását az alábbiak egyike biztosítja:

  • Egy tartalék akkumulátor (opcionális komponens egyes OpenMV Cam-eken).

  • Egy hálózati időprotokoll, mint például az ntptime (hálózati kapcsolatot igényel).

  • Minden bekapcsoláskor manuálisan beállítva. Az RTC ezután jellemzően fennmarad a szoftveres újraindításokon át, de áramkimaradás esetén elveszik, hacsak nincs tartalék akkumulátor beszerelve.

Ha a naptári idő nincs fenntartva, akkor az alábbi, az aktuális abszolút időre hivatkozó függvények nem a várt módon fognak viselkedni.

Függvények

time.gmtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]
time.localtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]

Az Epoch óta (lásd fent) eltelt másodpercekben kifejezett secs idő átalakítása egy 8 elemű tuple-lé, amely a következőket tartalmazza: (year, month, mday, hour, minute, second, weekday, yearday) Ha a secs nincs megadva vagy None, akkor az RTC aktuális ideje kerül felhasználásra.

A gmtime() függvény egy dátum-idő tuple-t ad vissza UTC-ben, a localtime() pedig egy dátum-idő tuple-t ad vissza helyi időben.

A 8 elemű tuple bejegyzéseinek formátuma a következő:

  • year tartalmazza a századot (például 2014).

  • month értéke 1-12

  • mday értéke 1-31

  • hour értéke 0-23

  • minute értéke 0-59

  • second értéke 0-59

  • weekday értéke 0-6 a hétfő-vasárnap napokhoz

  • yearday értéke 1-366

time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int

Ez a localtime inverz függvénye. Argumentuma egy teljes 8 elemű tuple, amely egy időt fejez ki a localtime szerint. Egy egész számot ad vissza, amely az időkorszak óta eltelt másodpercek száma.

time.sleep(seconds: float) None

Alvás a megadott számú másodpercig. A seconds lehet lebegőpontos szám is, hogy másodperc töredékéig tartó alvást valósítson meg. Finomabb felbontású vagy csak egész számú késleltetésekhez használja a sleep_ms() és sleep_us() függvényeket.

A sleep() hívása, beleértve a sleep(0)-t is, garantáltan meghívja a függőben lévő visszahívási függvényeket.

time.sleep_ms(ms: int) None

Késleltetés a megadott számú milliszekundumig, amelynek pozitívnak vagy 0-nak kell lennie.

Ez a függvény legalább a megadott számú milliszekundumig késleltet, de ennél tovább is tarthat, ha más feldolgozásnak kell történnie, például megszakításkezelőknek vagy más szálaknak. A ms értékeként 0 megadása esetén is megengedett, hogy ez az egyéb feldolgozás megtörténjen. Pontosabb késleltetésekhez használja a sleep_us() függvényt.

A sleep_ms() hívása, beleértve a sleep_ms(0)-t is, garantáltan meghívja a függőben lévő visszahívási függvényeket.

time.sleep_us(us: int) None

Késleltetés a megadott számú mikroszekundumig, amelynek pozitívnak vagy 0-nak kell lennie.

Ez a függvény legalább us mikroszekundum pontos késleltetését próbálja biztosítani, de tovább is tarthat, ha a rendszernek más, magasabb prioritású feldolgozást kell végeznie.

time.ticks_ms() int

Egy növekvő milliszekundum-számlálót ad vissza tetszőleges kezdőponttal, amely egy bizonyos érték után körbefordul.

A körbefordulási érték nincs explicit módon közzétéve, de a tárgyalás egyszerűsítése érdekében TICKS_MAX-ként fogunk rá hivatkozni. Az értékek periódusa TICKS_PERIOD = TICKS_MAX + 1. A TICKS_PERIOD garantáltan kettő hatványa, de egyébként portonként eltérhet. Ugyanaz a periódusérték kerül felhasználásra a ticks_ms(), ticks_us(), ticks_cpu() függvények mindegyikénél (az egyszerűség kedvéért). Így ezek a függvények a [0 .. TICKS_MAX] tartományba eső értéket adnak vissza, beleértve a határokat, összesen TICKS_PERIOD darab értéket. Vegye figyelembe, hogy csak nem negatív értékek használatosak. Az értékek nagy részét, amelyeket ezek a függvények visszaadnak, átlátszatlanként kell kezelnie. Az egyetlen rajtuk elérhető művelet az alább leírt ticks_diff() és ticks_add() függvények.

Megjegyzés: Standard matematikai műveletek (+, -) vagy relációs operátorok (<, <=, >, >=) közvetlen végrehajtása ezeken az értékeken érvénytelen eredményhez vezet. Matematikai műveletek végrehajtása, majd azok eredményének argumentumként való átadása a ticks_diff() vagy ticks_add() függvényeknek szintén érvénytelen eredményekhez vezet az utóbbi függvényeknél.

time.ticks_us() int

Ugyanúgy, mint a fenti ticks_ms(), de mikroszekundumban.

time.ticks_cpu() int

Hasonló a ticks_ms() és ticks_us() függvényekhez, de a rendszerben lehetséges legmagasabb felbontással. Ez általában a CPU órajele, és ezért kapta a függvény ezt a nevet. De nem feltétlenül CPU órajel, helyette használható a rendszerben elérhető más időforrás is (pl. nagy felbontású időzítő). Ennek a függvénynek a pontos időegysége (felbontása) nincs meghatározva a time modul szintjén, de egy adott port dokumentációja konkrétabb információt nyújthat. Ez a függvény nagyon finom teljesítményméréshez vagy nagyon szoros valós idejű ciklusokhoz készült. Kerülje a használatát hordozható kódban. Minden OpenMV Cam-en elérhető.

time.ticks_add(ticks: int, delta: int) int

Egy tick érték eltolása egy adott számmal, amely lehet pozitív vagy negatív. Egy adott ticks érték esetén ez a függvény lehetővé teszi a delta tick-kel előbbi vagy későbbi tick érték kiszámítását, a tick értékek moduláris-aritmetikai definícióját követve (lásd a fenti ticks_ms()-t). A ticks paraméternek a ticks_ms(), ticks_us() vagy ticks_cpu() függvények hívásának közvetlen eredményének kell lennie (vagy a ticks_add() korábbi hívásából). A delta azonban tetszőleges egész szám vagy numerikus kifejezés lehet. A ticks_add() hasznos az események/feladatok határidejének kiszámításához. (Megjegyzés: a határidőkkel való munkához a ticks_diff() függvényt kell használnia.)

Példák:

# Find out what ticks value there was 100ms ago
print(ticks_add(time.ticks_ms(), -100))

# Calculate deadline for operation and test for it
deadline = ticks_add(time.ticks_ms(), 200)
while ticks_diff(deadline, time.ticks_ms()) > 0:
    do_a_little_of_something()

# Find out TICKS_MAX used by this port
print(ticks_add(0, -1))
time.ticks_diff(ticks1: int, ticks2: int) int

A ticks_ms(), ticks_us() vagy ticks_cpu() függvények által visszaadott értékek közötti tick-különbség mérése, előjeles értékként, amely körbefordulhat.

Az argumentumok sorrendje ugyanaz, mint a kivonás operátoránál, a ticks_diff(ticks1, ticks2) ugyanazt jelenti, mint a ticks1 - ticks2. A ticks_ms() stb. függvények által visszaadott értékek azonban körbefordulhatnak, így a közvetlen kivonás használata rajtuk hibás eredményt fog adni. Ezért van szükség a ticks_diff()-re, amely moduláris (vagy pontosabban, gyűrű) aritmetikát valósít meg, hogy körbefordulási értékek esetén is helyes eredményt adjon (amennyiben nem túl távoliak egymástól, lásd lent). A függvény előjeles értéket ad vissza a [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] tartományban (ez a kettes komplemensű előjeles bináris egészek tipikus tartománydefiníciója). Ha az eredmény negatív, az azt jelenti, hogy a ticks1 időben korábban következett be, mint a ticks2. Egyébként azt jelenti, hogy a ticks1 a ticks2 után következett be. Ez csak akkor áll fenn, ha a ticks1 és ticks2 nem több, mint TICKS_PERIOD/2-1 tick-re vannak egymástól. Ha ez nem teljesül, hibás eredmény kerül visszaadásra. Konkrétan, ha két tick érték TICKS_PERIOD/2-1 tick-re van egymástól, azt az értéket adja vissza a függvény. Ha azonban TICKS_PERIOD/2 valós idejű tick telt el közöttük, a függvény helyette -TICKS_PERIOD/2-t ad vissza, azaz az eredményérték körbefordul a lehetséges értékek negatív tartományába.

A fenti megszorítások informális indoklása: Tegyük fel, hogy egy szobába van zárva, ahol az idő múlásának figyelésére csak egy standard, 12 osztású óra áll rendelkezésre. Ekkor, ha most a számlapra néz, és újabb 13 óráig nem néz oda (pl. ha hosszú álomba merül), akkor amikor végül újra odanéz, úgy tűnhet, mintha csak 1 óra telt volna el. Ennek a tévedésnek az elkerüléséhez egyszerűen nézzen rendszeresen az órára. Az alkalmazásának ugyanezt kell tennie. A „túl hosszú alvás” metafora közvetlenül leképezhető az alkalmazás viselkedésére is: ne hagyja, hogy az alkalmazása bármilyen egyetlen feladatot túl sokáig futtasson. Futtassa a feladatokat lépésekben, és az egyes lépések között végezzen időmérést.

A ticks_diff() különféle használati minták kiszolgálására lett tervezve, ezek között:

  • Lekérdezés időtúllépéssel. Ebben az esetben az események sorrendje ismert, és csak a ticks_diff() pozitív eredményeivel kell foglalkoznia:

    # Wait for GPIO pin to be asserted, but at most 500us
    start = time.ticks_us()
    while pin.value() == 0:
        if time.ticks_diff(time.ticks_us(), start) > 500:
            raise TimeoutError
    
  • Események ütemezése. Ebben az esetben a ticks_diff() eredménye negatív lehet, ha egy esemény túllépte a határidejét:

    # This code snippet is not optimized
    now = time.ticks_ms()
    scheduled_time = task.scheduled_time()
    if ticks_diff(scheduled_time, now) > 0:
        print("Too early, let's nap")
        sleep_ms(ticks_diff(scheduled_time, now))
        task.run()
    elif ticks_diff(scheduled_time, now) == 0:
        print("Right at time!")
        task.run()
    elif ticks_diff(scheduled_time, now) < 0:
        print("Oops, running late, tell task to run faster!")
        task.run(run_faster=true)
    

Megjegyzés: Ne adjon át time() értékeket a ticks_diff()-nek, ezeken normál matematikai műveleteket kell végeznie. De vegye figyelembe, hogy a time() is túlcsordulhat (és túl is fog csordulni). Ezt 2038-as probléma néven ismerik: https://en.wikipedia.org/wiki/Year_2038_problem .

time.time() int

Egy egész számként adja vissza az Epoch óta eltelt másodpercek számát, feltételezve, hogy az alapul szolgáló RTC be van állítva és fenntartott a fent leírtak szerint. Ha az RTC nincs beállítva, ez a függvény egy portspecifikus időbeli kezdőpont óta eltelt másodpercek számát adja vissza (akkumulátor által táplált RTC nélküli beágyazott kártyák esetén általában a bekapcsolás vagy az újraindítás óta). Ha hordozható MicroPython alkalmazást szeretne fejleszteni, nem szabad arra hagyatkoznia, hogy ez a függvény másodpercnél nagyobb pontosságot biztosít. Ha nagyobb pontosságra van szüksége abszolút időbélyegekkel, használja a time_ns()-t. Ha a relatív idők elfogadhatók, akkor használja a ticks_ms() és ticks_us() függvényeket. Ha naptári időre van szüksége, a gmtime() vagy localtime() argumentum nélkül jobb választás.

Eltérés a CPython-tól

A CPython-ban ez a függvény a Unix időkorszak (1970-01-01 00:00 UTC) óta eltelt másodpercek számát adja vissza lebegőpontos értékként, általában mikroszekundum pontossággal. Az OpenMV Cam-en egy egész számot ad vissza egy másodperc pontossággal – a hardver nem képes egyszerre hosszú időtartományt és másodperc alatti pontosságot is ábrázolni egy lebegőpontos számban –, és az időkorszak kártyánként eltér (lásd fent az Időkorszak részt). Akkumulátor által táplált, beállított RTC nélkül helyette a bekapcsolás/újraindítás óta eltelt másodperceket számolja.

time.time_ns() int

Hasonló a time()-hoz, de az Epoch óta eltelt nanoszekundumokat adja vissza egész számként (általában nagy egész számként, így a heapen fog allokálni).

Konstruktorok

class time.clock

Egy óra (clock) objektumot ad vissza.

Metódusok

tick() None

Megkezdi az eltelt idő követését.

fps() float

Leállítja az eltelt idő követését, és visszaadja az aktuális FPS-t (képkocka per másodperc).

Mindig hívja meg először a tick-et, mielőtt ezt a függvényt meghívná.

avg() float

Leállítja az eltelt idő követését, és visszaadja az aktuális átlagos eltelt időt milliszekundumban.

Mindig hívja meg először a tick-et, mielőtt ezt a függvényt meghívná.

reset() None

Visszaállítja az óra (clock) objektumot.