Mit SmartHomeNG existiert bereits eine Reihe zeitbezogener Daten über Shtime.get_instance().now(). Speziell für Datenbankabfragen kann es aber hilfreich sein, noch einige Zusatzitems zu haben. Diese werden im Rahmen dieses Artikels gezeigt.

Die Items


date:

    month:
        since:
            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.month.since.year
                    eval: str(sh.date.month.since.year()) + 'm'

        until:
            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.month.until.year
                    eval: str(sh.date.month.until.year()) + 'm'

    week:
        since:
            month:
                type: num
                cache: 'yes'
            year:
                type: num
                cache: 'yes'
        until:
            month:
                type: num
                cache: 'yes'
            year:
                type: num
                cache: 'yes'

    day:
        since:
            week:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.day.since.week
                    eval: str(sh.date.day.since.week()) + 'd'

            month:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.day.since.month
                    eval: str(sh.date.day.since.month()) + 'd'
            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.day.since.year
                    eval: str(sh.date.day.since.year()) + 'd'

        until:
            week:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.day.since.week
                    eval: str(sh.date.day.since.week()) + 'd'

            month:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.day.until.month
                    eval: str(sh.date.day.until.month()) + 'd'

            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.day.until.year
                    eval: str(sh.date.day.until.year()) + 'd'

    hour:
        since:
            midnight:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.since.midnight
                    eval: str(sh.date.hour.since.midnight()) + 'h'

            week:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.since.week
                    eval: str(sh.date.hour.since.week()) + 'h'

            month:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.since.month
                    eval: str(sh.date.hour.since.month()) + 'h'

            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.since.year
                    eval: str(sh.date.hour.since.year()) + 'h'

        until:
            midnight:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.until.midnight
                    eval: str(sh.date.hour.until.midnight()) + 'h'

            week:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.until.week
                    eval: str(sh.date.hour.until.week()) + 'h'

            month:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.until.month
                    eval: str(sh.date.hour.until.month()) + 'h'

            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.hour.until.year
                    eval: str(sh.date.hour.until.year()) + 'h'

    minute:
        since:
            hour:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.since.hour
                    eval: str(sh.date.minute.since.hour()) + 'i'

            midnight:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.since.midnight
                    eval: str(sh.date.minute.since.midnight()) + 'i'

            week:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.since.week
                    eval: str(sh.date.minute.since.week()) + 'i'

            month:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.since.month
                    eval: str(sh.date.minute.since.month()) + 'i'

            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.since.year
                    eval: str(sh.date.minute.since.year()) + 'i'

        until:
            hour:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.until.hour
                    eval: str(sh.date.minute.until.hour()) + 'i'

            midnight:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.until.midnight
                    eval: str(sh.date.minute.until.midnight()) + 'i'

            week:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.until.week
                    eval: str(sh.date.minute.until.week()) + 'i'

            month:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.until.month
                    eval: str(sh.date.minute.until.month()) + 'i'

            year:
                type: num
                cache: 'yes'
                dbstr:
                    type: str
                    cache: 'yes'
                    eval_trigger: date.minute.until.year
                    eval: str(sh.date.minute.until.year()) + 'i'

    second:
        since:
            minute:
                type: num

            hour:
                type: num

            midnight:
                type: num

            week:
                type: num

            month:
                type: num

            year:
                type: num

        until:

            minute:
                type: num

            hour:
                type: num

            midnight:
                type: num

            week:
                type: num

            month:
                type: num

            year:
                type: num

Die Logik

Als Logik wird unter logics/zeit.py die nachfolgende Datei angelegt.


# /logics/zeit.py
# !/usr/bin/env python3


from lib.shtime import Shtime
sh_now = Shtime.get_instance().now() # Funktionen def days_of_month(month, year): if month in [1, 3, 5, 7, 8, 10, 12]: days = 31 elif month in [4, 6, 9, 11]: days = 30 elif (year % 400 == 0) or ((year % 4 == 0) and not (year % 100 == 0)): # Schaltjahr days = 29 else: days = 28 return days def days_of_year(year): period_end = datetime.datetime(year, 12, 31) days_of_year = (period_end - datetime.datetime(period_end.year, 1, 1)).days + 1 return (days_of_year) def day_of_year(year, month, day): period_end = datetime.datetime(year, month, day) day_of_year = (period_end - datetime.datetime(period_end.year, 1, 1)).days + 1 return (day_of_year) # Sekunde/Minute sh.date.second.since.minute(sh_now.second) sh.date.second.until.minute(60 - sh_now.second - 1) # Minute/Stunde sh.date.minute.since.hour(sh_now.minute) sh.date.minute.until.hour(60 - sh_now.minute - 1) # Stunde/Tag sh.date.hour.since.midnight(sh_now.hour) sh.date.hour.until.midnight(24 - sh_now.hour - 1) # Tag/Woche sh.date.day.since.week(sh_now.isoweekday()) sh.date.day.until.week(7 - sh_now.isoweekday()) # Stunde/Woche sh.date.hour.since.week(sh.date.hour.since.midnight() + (24 * (sh.date.day.since.week() - 1))) sh.date.hour.until.week(sh.date.hour.until.midnight() + (24 * sh.date.day.until.week())) # Kalenderwoche/Jahr sh.date.week.since.year(sh_now.isocalendar()[1]) sh.date.week.until.year(52-sh_now.isocalendar()[1]) # Monat/Jahr sh.date.month.since.year(sh_now.month) sh.date.month.until.year(12 - sh_now.month) # Sekunde/Stunde sh.date.second.since.hour(sh.date.second.since.minute() + (60 * sh.date.minute.since.hour())) sh.date.second.until.hour(sh.date.second.until.minute() + (60 * sh.date.minute.until.hour())) # Sekunde/Tag sh.date.second.since.midnight(sh.date.second.since.minute() + (3600 * sh.date.hour.since.midnight())) sh.date.second.until.midnight(sh.date.second.until.minute() + (3600 * sh.date.hour.until.midnight())) # Minute/Tag sh.date.minute.since.midnight(sh.date.minute.since.hour() + (60 * sh.date.hour.since.midnight())) sh.date.minute.until.midnight(sh.date.minute.until.hour() + (60 * sh.date.hour.until.midnight())) # Minute/Woche sh.date.minute.since.week(sh.date.minute.since.hour() + (60 * sh.date.hour.since.week())) sh.date.minute.until.week(sh.date.minute.until.hour() + (60 * sh.date.hour.until.week())) # Sekunde/Woche sh.date.second.since.week(sh.date.second.since.minute() + (60 * sh.date.minute.since.week())) sh.date.second.until.week(sh.date.second.until.minute() + (60 * sh.date.minute.until.week())) # Tage/Monat sh.date.day.since.month(sh_now.day) sh.date.day.until.month(days_of_month(sh_now.month, sh_now.year) - sh.date.day.since.month() - 1) # Wochen/Monat sh.date.week.since.month((sh.date.day.since.month()-1)//7+1) sh.date.week.until.month((sh.date.day.until.month())//7) # Tage/Jahr sh.date.day.since.year(day_of_year(sh_now.year, sh_now.month, sh_now.day) - 1) sh.date.day.until.year(days_of_year(sh_now.year) - sh.date.day.since.year() - 1) # Stunde/Monat sh.date.hour.since.month((24 * sh.date.day.since.month()) + sh.date.hour.since.midnight()) sh.date.hour.until.month((24 * days_of_month(sh_now.month, sh_now.year)) - sh.date.hour.since.month() - 1) # Stunde/Jahr sh.date.hour.since.year((24 * sh.date.day.since.year()) + sh.date.hour.since.midnight()) sh.date.hour.until.year((24 * days_of_year(sh_now.year)) - sh.date.hour.since.year() - 1) # Minute/Monat sh.date.minute.since.month((60 * sh.date.hour.since.month()) + sh.date.minute.since.hour()) sh.date.minute.until.month(sh.date.minute.since.month() - (60 * sh.date.hour.until.month()) - 1) # Minute/Jahr sh.date.minute.since.year((60 * sh.date.hour.since.year()) + sh.date.minute.since.hour()) sh.date.minute.until.year((60 * sh.date.hour.until.year()) + sh.date.minute.until.hour()) # Sekunde/Monat sh.date.second.since.month((60 * sh.date.minute.since.month()) + sh.date.second.since.minute()) sh.date.second.until.month((60 * sh.date.minute.until.month()) + sh.date.second.until.minute()) # Sekunde/Jahr sh.date.second.since.year((60 * sh.date.minute.since.year()) + sh.date.second.since.minute()) sh.date.second.until.year((60 * sh.date.minute.until.year()) + sh.date.second.until.minute())

In der etc/logic.yaml wird sie wie folgt eingebunden:


zeitberechnung:
    filename: zeit.py
    crontab:
        -   init
        -   '* * * *'

Anwendungsbeispiel: Database Plugin

Neben der Anzeige der Daten, macht es vor allem Sinn, die Werte im Zusammenspiel mit (historischen) Datenbank-Daten zu verwenden. Ein Beispiel wäre wie folgt:


consumption_since_midnight:
	type: num
	eval: sh.knx.cellar.utility_room.water_meter.db('count>0', sh.date.minute.since.midnight.dbstr(), 'now')
	eval_trigger: knx.cellar.utility_room.water_meter
	database@mysqldb: init

Im Eval-Ausdruck wird die Anzahl der Werte > 0 ermittelt, die zwischen Mitternacht und dem IST-Zeitpunkt erfasst wurden. Da für 1 Liter jedes Mal ein Impuls mit einer „1“ erfasst wird, erhält man so minutengenau die Anzahl der Liter seit Mitternacht. Die Methode dbstr() in sh.date.minute.since.midnight.dbstr() liefert direkt den Wert, den das Database-Plugin benötigt. Präziser gesagt, hängt sie dem numerischen Wert noch ein „i“ an, so dass die Angabe auf Ebene des Plugins korrekt interpretiert wird.
Über die Methode .db auf dem Item, wird die Datenbankabfrage gestartet. Das Item muss dazu mit dem Database-Plugin verknüpft sein database@mysqldb: init und bereits Daten im abgefragten Zeitraum erfasst haben.

(Das Titelbild ist unter der Creative Commons Zero (CC0) Lizenz veröffentlicht und wurde von www.pexels.com bezogen.)


3 Kommentare

Marc René Frieß · 3. Mai 2018 um 17:21

Ich habe mir das jetzt angeschaut und sehe noch nicht so recht den Verwendungszweck Deiner zusätzlichen Items?

Die Beispiele im 2ten Post sind ok, die aber alle in den Artikel aufzunehmen und zu erklären bläht den Inhalt ziemlich auf und verwirrt eher..
Die lasse ich auch mal als Kommentar. Ist ja legitim.

Ich habe mir zudem erlaubt Deine Kommentare zu formatieren. Der interessierte Leser kann sich die ja dann im Nachgang „einverleiben“.
Bitte in Zukunft selber machen.

sisamiwe · 2. Mai 2018 um 20:26

Bei der Abfrage bzw. Berechnung von Verbrauchsdaten hätte ich auch noch ein Beispiel.
Ich ermittle des Heizölverbrauch über die Einschaltzeit des Brenners (via einem KNX-Binäreingang). Die Logik dahinter ist einfach: Der Brenner braucht 2l pro Betriebsstunde. Die Einschaltzeit des Brenners wird ermittelt und in die DB geschrieben. Der jeweiligen Verbrauchswerte werden aus den DB-Werten ermittelt.

Hier meine Items:


heizung:

    brenner:
        name: Brennerstatus Heizung
        type: bool
        visu_acl: 'ro'
        database: 'init'
        knx_dpt: 1
        knx_cache: 0/3/91
        knx_reply: 0/3/91

        betriebsstunden:
            name: Betriebsstundenzähler Brenner Heizung in Sekunden
            type: num
            visu_acl: 'ro'
            database: 'init'
            eval: sh.heizung.brenner.betriebsstunden() + int(sh.heizung.brenner.prev_value()) * sh.heizung.brenner.prev_age() + int(sh.heizung.brenner.prev_value()) * -10
            eval_trigger: heizung.brenner

            gesamt:
                name: Betriebsstundenzähler Brenner Heizung in Stunden
                type: num
                visu_acl: 'ro'
                database: 'init'
                eval: round(sh...() / 60 / 60, 2)
                eval_trigger:
                  - ..
                  - heizung.recalc

            heute:
                type: num
                visu_acl: 'ro'
                eval: round((sh...() - sh...db('max', sh.time.minute.since.midnight.dbstr(), sh.time.minute.since.midnight.dbstr())) / 60 /60, 2)
                eval_trigger:
                  - ..
                  - heizung.recalc
                cache: 'yes'

            woche:
                type: num
                visu_acl: 'ro'
                eval: round((sh...() - sh...db('max', sh.time.minute.since.week.dbstr(), sh.time.minute.since.week.dbstr())) / 60 / 60, 2)
                eval_trigger:
                  - ..
                  - heizung.recalc
                cache: 'yes'

            monat:
                type: num
                visu_acl: 'ro'
                eval: round((sh...() - sh...db('max', sh.time.minute.since.month.dbstr(), sh.time.minute.since.month.dbstr())) / 60 / 60, 2)
                eval_trigger:
                  - ..
                  - heizung.recalc
                cache: 'yes'

            jahr:
                type: num
                visu_acl: 'ro'
                eval: round((sh...() - sh...db('max', sh.time.minute.since.year.dbstr(), sh.time.minute.since.year.dbstr())) / 60 / 60, 2)
                eval_trigger:
                  - ..
                  - heizung.recalc
                cache: 'yes'

            gestern:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', sh.time.minute.since.midnight.dbstr(), sh.time.minute.since.midnight.dbstr()) - sh...db('max', str(sh.time.minute.since.midnight() + 1440) + 'i', str(sh.time.minute.since.midnight() + 1440) + 'i')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'
                database: 'yes'

            gestern_minus1:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.midnight() + 1440) + 'i', str(sh.time.minute.since.midnight() + 1440) + 'i') - sh...db('max', str(sh.time.minute.since.midnight() + 2880) + 'i', str(sh.time.minute.since.midnight() + 2880) + 'i')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'
            
            gestern_minus2:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.midnight() + 2880) + 'i', str(sh.time.minute.since.midnight() + 2880) + 'i') - sh...db('max', str(sh.time.minute.since.midnight() + 4320) + 'i', str(sh.time.minute.since.midnight() + 4320) + 'i')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'
                
            gestern_minus3:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.midnight() + 4320) + 'i', str(sh.time.minute.since.midnight() + 4320) + 'i') - sh...db('max', str(sh.time.minute.since.midnight() + 5670) + 'i', str(sh.time.minute.since.midnight() + 5670) + 'i')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'
                
            gestern_minus4:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.midnight() + 5670) + 'i', str(sh.time.minute.since.midnight() + 5670) + 'i') - sh...db('max', str(sh.time.minute.since.midnight() + 7200) + 'i', str(sh.time.minute.since.midnight() + 7200) + 'i')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'

            gestern_minus5:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.midnight() + 7200) + 'i', str(sh.time.minute.since.midnight() + 7200) + 'i') - sh...db('max', str(sh.time.minute.since.midnight() + 8640) + 'i', str(sh.time.minute.since.midnight() + 8640) + 'i')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'                
                
            vorwoche:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', sh.time.minute.since.week.dbstr(), sh.time.minute.since.week.dbstr()) - sh...db('max', str(sh.time.minute.since.week() + 10080) + 'i', str(sh.time.minute.since.week() + 10080) + 'i')) / 60 / 60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes' 

            vorwoche_minus1:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.week() + 10080) + 'i', str(sh.time.minute.since.week() + 10080) + 'i') - sh...db('max', str(sh.time.minute.since.week() + 20160) + 'i', str(sh.time.minute.since.week() + 20160) + 'i')) / 60 / 60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'
                
            vorwoche_minus2:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.week() + 20160) + 'i', str(sh.time.minute.since.week() + 20160) + 'i') - sh...db('max', str(sh.time.minute.since.week() + 30240) + 'i', str(sh.time.minute.since.week() + 30240) + 'i')) / 60 / 60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'
                
            vorwoche_minus3:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.minute.since.week() + 30240) + 'i', str(sh.time.minute.since.week() + 30240) + 'i') - sh...db('max', str(sh.time.minute.since.week() + 40320) + 'i', str(sh.time.minute.since.week() + 40320) + 'i')) / 60 / 60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 * * = 1
                cache: 'yes'
                
            vormonat:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.hour.since.month()) + 'h', str(sh.time.hour.since.month()) + 'h') - sh...db('max', str(sh.time.hour.since.month() + 730) + 'h', str(sh.time.hour.since.month() + 730) + 'h')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 1 * = 1
                cache: 'yes'
                
            vormonat_minus1:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.hour.since.month() + 730) + 'h', str(sh.time.hour.since.month() + 730) + 'h') - sh...db('max', str(sh.time.hour.since.month() + 1460) + 'h', str(sh.time.hour.since.month() + 1460) + 'h')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 1 * = 1
                cache: 'yes'    
                
            vormonat_minus2:
                type: num
                visu_acl: 'ro'
                eval: round((sh...db('max', str(sh.time.hour.since.month() + 1460) + 'h', str(sh.time.hour.since.month() + 1460) + 'h') - sh...db('max', str(sh.time.hour.since.month() + 2190) + 'h', str(sh.time.hour.since.month() + 2190) + 'h')) / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 1 * = 1
                cache: 'yes'  

            vormonat_zaehlerstand:
                type: num
                visu_acl: 'ro'
                eval: round(sh...db('max', str(sh.time.hour.since.month()) + 'h', str(sh.time.hour.since.month()) + 'h') / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 1 * = 1
                cache: 'yes'
                
            vormonat_minus1_zaehlerstand:
                type: num
                visu_acl: 'ro'
                eval: round(sh...db('max', str(sh.time.hour.since.month() + 730) + 'h', str(sh.time.hour.since.month() + 730) + 'h') / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 1 * = 1
                cache: 'yes'
            
            vormonat_minus2_zaehlerstand:
                type: num
                visu_acl: 'ro'
                eval: round(sh...db('max', str(sh.time.hour.since.month() + 1460) + 'h', str(sh.time.hour.since.month() + 1460) + 'h') / 60 /60, 2)
                eval_trigger: heizung.recalc
                crontab: 1 0 1 * = 1
                cache: 'yes'

Interessant?

sisamiwe · 2. Mai 2018 um 20:20

Hi,
ich habe das auch so in Verwendung.
Um bei Verbrauchsangaben den richtigen Monat zu haben, habe ich die Logik im folgende Punkte ergänzt:


# Aktueller Monat
sh.time.month.current(sh_now.month)

# Aktuelles Jahr
sh.time.year.current(sh_now.year)

# Aktuelles Monat/Jahr
today_date = datetime.date.today()
sh.time.date.current_month(today_date.strftime("%m/%Y"))

# Letzter Monat/Jahr
last_month = today_date - relativedelta(months=1)
sh.time.date.last_month(last_month.strftime("%m/%Y"))

# Vorletzter Monat/Jahr
last_month_but_one = today_date - relativedelta(months=2)
sh.time.date.last_month_but_one(last_month_but_one.strftime("%m/%Y"))

# VorVorletzter Monat/Jahr
last_month_but_two = today_date - relativedelta(months=3)
sh.time.date.last_month_but_two(last_month_but_two.strftime("%m/%Y"))

und die Items:


    date:

        current_month:
            type: foo
            
        last_month:
            type: foo    
        
        last_month_but_one:
            type: foo
        
        last_month_but_two:
            type: foo  
    
    year:

        current:
            type: num

GGf. kannst Du das ergänzen

Michael

Schreibe einen Kommentar

Avatar-Platzhalter

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert