Hallo,
kann man diese API für FHEM nutzen, wenn ja, wie?
https://github.com/Vertretungsapp/indiware-api
matze1999
Wenn du gerade erst anfängst, kannst du versuchen, die Daten über Perl/HTTP-GET in FHEM abzurufen und sie anschließend mit Internal-Command weiterzuverarbeiten. So hat man einen relativ einfachen Einstieg, bevor man einen eigenen Modulbau oder komplexere Skripte angeht. Übrigens, eine sehr nützliche Website (https://slotloungeonline.de/app/). Sie hat mir schon mehrmals in bestimmten Situationen geholfen.
Hallo,
das habe ich schon versucht aber ist https, und http://name:passwort@... funktioniert nicht zum einloggen.
matze1999
Wenn das nur basic auth ist, kannst du einfach den Authorization-Header benutzen.
Hallo, ich bin schon einen Schritt weiter, das login klappt, und ich habe auch eine xml die ich auslesen kann, dafür gibt es ein Beispile bei indieware:
https://www.stundenplan24.de/10000000/vplan/vdaten/VplanKl.xml
mit ....VplanKLYYYYMMDD.xml kann ich auch den gewünschten Tag angeben. allerdings komme ich hier nicht weiter.
Wie kann ich bei HTTPMOD das Datum für die Abfrage mit übergeben, Mir schwebt vor, immer zu einer bestimmten Zeit für den nächsten Tag die xml abrufe, nach der Klasse 6d suche <Kurz>6d</Kurz> und nach dem Wort "Ausfall" und dann readings habe, die mir anzeigen, da ist ein Ausfall der Stunde X <St>X</St> ist. Hier mal eine Teil aus der xml:
<Pl>
<Std>
<St>1</St>
<Beginn>08:05</Beginn>
<Ende>08:50</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>48</Nr>
<If>KU Lehrer Ausfall</If>
</Std>
<Std>
<St>2</St>
<Beginn>08:55</Beginn>
<Ende>09:40</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>48</Nr>
<If>KU Lehrer Ausfall</If>
</Std>
<Std>
<St>3</St>
<Beginn>10:10</Beginn>
<Ende>10:55</Ende>
<Fa>SP M</Fa>
<Ku2>SP M</Ku2>
<Le>RW</Le>
<Ra>A-TH3</Ra>
<Nr>33</Nr>
<If/>
</Std>
<Std>
<St>3</St>
<Beginn>10:10</Beginn>
<Ende>10:55</Ende>
<Fa>SP J</Fa>
<Ku2>SP J</Ku2>
<Le>CL</Le>
<Ra>A-TH2</Ra>
<Nr>46</Nr>
<If/>
</Std>
<Std>
<St>4</St>
<Beginn>11:00</Beginn>
<Ende>11:45</Ende>
<Fa>SP M</Fa>
<Ku2>SP M</Ku2>
<Le>RW</Le>
<Ra>A-TH3</Ra>
<Nr>33</Nr>
<If/>
</Std>
<Std>
<St>4</St>
<Beginn>11:00</Beginn>
<Ende>11:45</Ende>
<Fa>SP J</Fa>
<Ku2>SP J</Ku2>
<Le>CL</Le>
<Ra>A-TH2</Ra>
<Nr>46</Nr>
<If/>
</Std>
<Std>
<St>5</St>
<Beginn>11:50</Beginn>
<Ende>12:35</Ende>
<Fa FaAe="FaGeaendert">EN</Fa>
<Le>IK</Le>
<Ra>H-221</Ra>
<Nr>402</Nr>
<If/>
</Std>
<Std>
<St>6</St>
<Beginn>13:25</Beginn>
<Ende>14:10</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>402</Nr>
<If>FD Lehrer Ausfall</If>
</Std>
<Std>
<St>7</St>
<Beginn>14:15</Beginn>
<Ende>15:00</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>402</Nr>
<If>FD Leher Ausfall</If>
</Std>
Die größte Hürde für mich ist die automatische HTTPMOD Abfrage mit Datum des nächsten Tages.
matze1999
hier noch mal der vollständige Block für eine Klasse (5e):
<Kl>
<Kurz>5e</Kurz>
<Hash/>
<KlStunden>
<KlSt ZeitVon="07:15" ZeitBis="08:00">0</KlSt>
<KlSt ZeitVon="08:05" ZeitBis="08:50">1</KlSt>
<KlSt ZeitVon="08:55" ZeitBis="09:40">2</KlSt>
<KlSt ZeitVon="10:10" ZeitBis="10:55">3</KlSt>
<KlSt ZeitVon="11:00" ZeitBis="11:45">4</KlSt>
<KlSt ZeitVon="11:50" ZeitBis="12:35">5</KlSt>
<KlSt ZeitVon="13:25" ZeitBis="14:10">6</KlSt>
<KlSt ZeitVon="14:15" ZeitBis="15:00">7</KlSt>
<KlSt ZeitVon="15:05" ZeitBis="15:50">8</KlSt>
</KlStunden>
<Kurse>
<Ku>
<KKz KLe="CL">SP J</KKz>
</Ku>
<Ku>
<KKz KLe="RW">SP M</KKz>
</Ku>
</Kurse>
<Unterricht>
<Ue>
<UeNr UeLe="RW" UeFa="SPO" UeGr="SP M">33</UeNr>
</Ue>
<Ue>
<UeNr UeLe="MaL" UeFa="DeuFö">38</UeNr>
</Ue>
<Ue>
<UeNr UeLe="HeH" UeFa="MaFö">39</UeNr>
</Ue>
<Ue>
<UeNr UeLe="MS" UeFa="DE">40</UeNr>
</Ue>
<Ue>
<UeNr UeLe="IK" UeFa="EN">41</UeNr>
</Ue>
<Ue>
<UeNr UeLe="HeH" UeFa="MA">42</UeNr>
</Ue>
<Ue>
<UeNr UeLe="MK" UeFa="BIO">43</UeNr>
</Ue>
<Ue>
<UeNr UeLe="MH" UeFa="GE">44</UeNr>
</Ue>
<Ue>
<UeNr UeLe="NW" UeFa="GEO">45</UeNr>
</Ue>
<Ue>
<UeNr UeLe="CL" UeFa="SPO" UeGr="SP J">46</UeNr>
</Ue>
<Ue>
<UeNr UeLe="CS" UeFa="REV">47</UeNr>
</Ue>
<Ue>
<UeNr UeLe="AgK" UeFa="KU">48</UeNr>
</Ue>
<Ue>
<UeNr UeLe="StS" UeFa="MU">49</UeNr>
</Ue>
<Ue>
<UeNr UeLe="UB" UeFa="TC">50</UeNr>
</Ue>
<Ue>
<UeNr UeLe="IK" UeFa="FD">402</UeNr>
</Ue>
<Ue>
<UeNr UeLe="JN" UeFa="TC">371</UeNr>
</Ue>
</Unterricht>
<Pl>
<Std>
<St>1</St>
<Beginn>08:05</Beginn>
<Ende>08:50</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>48</Nr>
<If>KU Lehrer Ausfall</If>
</Std>
<Std>
<St>2</St>
<Beginn>08:55</Beginn>
<Ende>09:40</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>48</Nr>
<If>KU Lehrer Ausfall</If>
</Std>
<Std>
<St>3</St>
<Beginn>10:10</Beginn>
<Ende>10:55</Ende>
<Fa>SP M</Fa>
<Ku2>SP M</Ku2>
<Le>RW</Le>
<Ra>A-TH3</Ra>
<Nr>33</Nr>
<If/>
</Std>
<Std>
<St>3</St>
<Beginn>10:10</Beginn>
<Ende>10:55</Ende>
<Fa>SP J</Fa>
<Ku2>SP J</Ku2>
<Le>CL</Le>
<Ra>A-TH2</Ra>
<Nr>46</Nr>
<If/>
</Std>
<Std>
<St>4</St>
<Beginn>11:00</Beginn>
<Ende>11:45</Ende>
<Fa>SP M</Fa>
<Ku2>SP M</Ku2>
<Le>RW</Le>
<Ra>A-TH3</Ra>
<Nr>33</Nr>
<If/>
</Std>
<Std>
<St>4</St>
<Beginn>11:00</Beginn>
<Ende>11:45</Ende>
<Fa>SP J</Fa>
<Ku2>SP J</Ku2>
<Le>CL</Le>
<Ra>A-TH2</Ra>
<Nr>46</Nr>
<If/>
</Std>
<Std>
<St>5</St>
<Beginn>11:50</Beginn>
<Ende>12:35</Ende>
<Fa FaAe="FaGeaendert">EN</Fa>
<Le>IK</Le>
<Ra>H-221</Ra>
<Nr>402</Nr>
<If/>
</Std>
<Std>
<St>6</St>
<Beginn>13:25</Beginn>
<Ende>14:10</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>402</Nr>
<If>FD Lehrer Ausfall</If>
</Std>
<Std>
<St>7</St>
<Beginn>14:15</Beginn>
<Ende>15:00</Ende>
<Fa FaAe="FaGeaendert">---</Fa>
<Le LeAe="LeGeaendert"/>
<Ra RaAe="RaGeaendert"/>
<Nr>402</Nr>
<If>FD Lehrer Ausfall</If>
</Std>
</Pl>
</Kl>
Hallo,
mit diesen Readings bekomme ich die Ausfallstunde und den Text angezeigt, allerdings geht das in die nächste klasse über, ich weiss nicht wie ich das auf den Bereich der Klasse 5e begrenze:
attr Stundenplan reading01Name Ausfall_1
attr Stundenplan reading01Regex (?s)<Kl\b[^>]*>.*?<Kurz>\s*5e\s*</Kurz>.*?(?:.*?<Std\b[^>]*>.*?<If>[^<]*Ausfall[^<]*</If>.*?</Std>){0}.*?<Std\b[^>]*>.*?<St>\s*(\d+)\s*</St>.*?<If>\s*([^<]*Ausfall[^<]*)\s*</If>.*?</Std>
attr Stundenplan reading02Name Ausfall_2
attr Stundenplan reading02Regex (?s)<Kl\b[^>]*>.*?<Kurz>\s*5e\s*</Kurz>.*?(?:.*?<Std\b[^>]*>.*?<If>[^<]*Ausfall[^<]*</If>.*?</Std>){1}.*?<Std\b[^>]*>.*?<St>\s*(\d+)\s*</St>.*?<If>\s*([^<]*Ausfall[^<]*)\s*</If>.*?</Std>
attr Stundenplan reading03Name Ausfall_3
attr Stundenplan reading03Regex (?s)<Kl\b[^>]*>.*?<Kurz>\s*5e\s*</Kurz>.*?(?:.*?<Std\b[^>]*>.*?<If>[^<]*Ausfall[^<]*</If>.*?</Std>){2}.*?<Std\b[^>]*>.*?<St>\s*(\d+)\s*</St>.*?<If>\s*([^<]*Ausfall[^<]*)\s*</If>.*?</Std>
attr Stundenplan reading04Name Ausfall_4
attr Stundenplan reading04Regex (?s)<Kl\b[^>]*>.*?<Kurz>\s*5e\s*</Kurz>.*?(?:.*?<Std\b[^>]*>.*?<If>[^<]*Ausfall[^<]*</If>.*?</Std>){3}.*?<Std\b[^>]*>.*?<St>\s*(\d+)\s*</St>.*?<If>\s*([^<]*Ausfall[^<]*)\s*</If>.*?</Std>
attr Stundenplan reading05Name Ausfall_5
attr Stundenplan reading05Regex (?s)<Kl\b[^>]*>.*?<Kurz>\s*5e\s*</Kurz>.*?(?:.*?<Std\b[^>]*>.*?<If>[^<]*Ausfall[^<]*</If>.*?</Std>){4}.*?<Std\b[^>]*>.*?<St>\s*(\d+)\s*</St>.*?<If>\s*([^<]*Ausfall[^<]*)\s*</If>.*?</Std>
Und wie ich in der Abfrage das Datum neu setzen kann, weiss ich auch noch nicht:
defmod Stundenplan HTTPMOD https://user:pass@www.stundenplan24.de/10000111/mobil/mobdaten/PlanKlYYYYMMDD.xml
matze1999
eine runde im Forum gesucht, einen Schritt weiter, abfrage automatisch für den nächsten Tag:
defmod Stundenplan HTTPMOD https://user:pass@www.stundenplan24.de/100000111/mobil/mobdaten/PlanKl%%DATE%%.xml 86400
attr Stundenplan replacement01Mode expression
attr Stundenplan replacement01Regex %%DATE%%
attr Stundenplan replacement01Value POSIX::strftime("%Y%m%d", localtime(time + 86400));;
So, jetzt nur noch das Problem, dass er im Bereich der Klasse 5e, nach "Ausfall" sucht und mir dann die Stunde und den Text <if> .. </if> als reading (oder zwei Readings) ausgibt, wenn vorhanden.
Hallo,
ich habe jetzt für mich, auch unter Einsatz von Chatgpt, eine Lösung gefunden. Ich habe ein script, dass ich den Stundenplan des nächsten Tages abrufen lasse und in ein dummy Device "Stundenplan" in FHEM als separate readings stundenweise schreiben lasse:
#!/bin/bash
# Konfiguration
FHEM_HOST="localhost"
FHEM_PORT="7072"
FHEM_DEVICE="Stundenplan"
INFO_READING_PREFIX="Stunde"
# Datum des nächsten Tages im Format YYYYMMDD
NEXT_DAY_DATE=$(date -d "+1 day" +"%Y%m%d")
URL="https://[user]:[pass]@www.stundenplan24.de/[Schulnummer]/mobil/mobdaten/PlanKl${NEXT_DAY_DATE}.xml"
# XML-Datei herunterladen
curl -s "${URL}" > /tmp/stundenplan.xml
# Überprüfen, ob die XML-Datei gültig ist
if [ ! -s /tmp/stundenplan.xml ]; then
perl fhem.pl "${FHEM_HOST}:${FHEM_PORT}" "setreading ${FHEM_DEVICE} status Error: No XML file or empty"
exit 1
fi
# >> NEUE LOGIK: Alle alten Readings löschen
perl fhem.pl "${FHEM_HOST}:${FHEM_PORT}" "deletereading ${FHEM_DEVICE} .*"
# Alle Stunden-Informationen für die Klasse mit xmlstarlet auslesen
AUSGABE=$(xmlstarlet sel -t -m "//Kl[Kurz='[Klasse]']/Pl/Std" \
-v "St" -o "|" -v "Fa" -o "|" -v "If" -n /tmp/stundenplan.xml)
# die neuen Kommandos in ein bash array schreiben
declare -a FHEM_COMMANDS
# Für jede Stunde ausführen und die Daten speichern
COUNTER=0
while IFS='|' read -r STUNDE FA_INFO IF_INFO; do
# LeereZeilen im xmlstarlet output ignorieren
if [ -z "$STUNDE" ]; then
continue
fi
# Zähler erhöhen
COUNTER=$((COUNTER + 1))
# Default für fehlende Inhalte setzen
if [ -z "$FA_INFO" ]; then
FA_INFO="$EMPTY_INFO_STRING"
fi
# Alle Readings Kommandos dem FHEM_COMMANDS array zufügen
FHEM_COMMANDS+=("setreading ${FHEM_DEVICE} ${INFO_READING_PREFIX}${COUNTER}_Stunde ${STUNDE}")
FHEM_COMMANDS+=("setreading ${FHEM_DEVICE} ${INFO_READING_PREFIX}${COUNTER}_Fa ${FA_INFO}")
# ODas'If' reading hinzufügen, wenn es nicht leer ist
if [ -n "$IF_INFO" ]; then
FHEM_COMMANDS+=("setreading ${FHEM_DEVICE} ${INFO_READING_PREFIX}${COUNTER}_If ${IF_INFO}")
fi
done <<< "$AUSGABE"
# Wenn keine Stunden gefunden werden Status setzen
if [ "${COUNTER}" -eq 0 ]; then
FHEM_COMMANDS+=("setreading ${FHEM_DEVICE} status_info Kein Stundenplan für Klasse 5d gefunden.")
fi
# Anzahl der Gesamtstunden setzen
FHEM_COMMANDS+=("setreading ${FHEM_DEVICE} Stundenanzahl ${COUNTER}")
# Dass array abarbeiten und jedes Kommando zu FHEM senden
for cmd in "${FHEM_COMMANDS[@]}"; do
perl fhem.pl "${FHEM_HOST}:${FHEM_PORT}" "$cmd"
done
# das Hilfsfile löschen
rm /tmp/stundenplan.xml
exit 0
Das ganze lasse ich zu bestimmten Zeiten aus FHEM ausführen, und dann im Device Stundenplan anzeigen:
mit diesem stateFormat
{
# Translation table for German weekdays and months
my %weekdays = (
"Mon" => "Montag",
"Tue" => "Dienstag",
"Wed" => "Mittwoch",
"Thu" => "Donnerstag",
"Fri" => "Freitag",
"Sat" => "Samstag",
"Sun" => "Sonntag"
);
my %months = (
"Jan" => "Januar",
"Feb" => "Februar",
"Mar" => "März",
"Apr" => "April",
"May" => "Mai",
"Jun" => "Juni",
"Jul" => "Juli",
"Aug" => "August",
"Sep" => "September",
"Oct" => "Oktober",
"Nov" => "November",
"Dec" => "Dezember"
);
# Calculate the date for tomorrow (current time + 86400 seconds)
my $next_day_timestamp = time + 86400;
my $date = localtime($next_day_timestamp);
my ($weekday_en, $month_en, $day, $time, $year) = split(/\s+/, $date);
# Translate the weekday and month to German
my $weekday_de = $weekdays{$weekday_en};
my $month_de = $months{$month_en};
# Build the final output string
my $output = "$weekday_de, $day. $month_de $year<br><br>";
for (my $i=1; $i<=ReadingsVal($name,"Stundenanzahl",0); $i++) {
my $stunde = ReadingsVal($name,"Stunde".$i."_Stunde","");
my $fach = ReadingsVal($name,"Stunde".$i."_Fa","");
my $info = ReadingsVal($name,"Stunde".$i."_If","");
if ($stunde ne "") {
$output .= "Stunde $stunde: $fach";
if ($info ne "") {
$output .= " ($info)";
}
$output .= "<br>";
}
}
return $output;
}
Das sieht dann so aus:
matze1999
PS: das ist richtig dargestellt, die ersten beiden Stunden sind geteilt, deshalb werden sie doppelt dargestellt.