Weiter zum Inhalt

Skripten / Logik

16.7k Themen 215.2k Beiträge

Hilfe zu JavaScript, Blockly, TypeScript, Node-RED, Scenes und text2command

NEWS

Unterkategorien


  • Hilfe für Skripterstellung mit JavaScript

    3k 50k
    3k Themen
    50k Beiträge
    maxclaudiM
    @paul53 sagte: Es wäre schön, wenn Zendure die Bedeutung dieses Bits mitteilen würde. Zendure ist bzw. war in der Vergangenheit sehr sparsam mit Informationen. Oft ist die spärliche API-Dokumentation teilweise unvollständig oder nicht richtig. @paul53 sagte: Wenn es in neueren API-Versionen immer gesetzt ist, könnte man es auch maskieren. Darum frage ich ja. Diesen Schritt würde ich erst gehen, wenn die Dokumentation – wenn auch nur spärlich – überhaupt auf API 3 aktualisiert wird oder genügend eigene Untersuchungen dies bestätigen. @paul53 sagte: Wenn die Grenze erreicht ist, schaltet die Notstromdose ab und ioBroker läuft dann nicht mehr. Mich würde interessieren, unter welchen Bedingungen das beobachtet wurde. Für mich ist aktuell noch unklar, wie sich die Grid-Off-Steckdose verhält, wenn bei Erreichen von MinSoC gleichzeitig ausreichend PV-Leistung vorhanden ist, das Gerät mit dem Netz verbunden ist, oder AC-Laden aktiviert ist. Dazu habe ich bislang leider keine eindeutige Aussage/Information von Zendure gefunden. Aus den verfügbaren Informationen geht lediglich hervor, dass die Off-Grid-Steckdose ein eigenständiger EPS-/Notstrom-Ausgang ist, der primär aus der Batterie versorgt wird. Der SF800 Pro kann gleichzeitig netzparallel arbeiten und die Off-Grid-Steckdose versorgen. Zendure Zitat: Kann der SolarFlow 800 Pro 2 sowohl im netzgekoppelten als auch im netzunabhängigen Modus gleichzeitig arbeiten? Ja, es unterstützt die gleichzeitige Nutzung der Off-Grid- und Netzeinspeisungsfunktion, wobei die Gesamtleistung 1000 W nicht überschreiten darf. Bei alleiniger Nutzung der Off-Grid-Funktion beträgt die maximale Entladeleistung der Off-Grid-AC-Schnittstelle 1000 W. Quelle: Zendure SolarFlow 800 Pro 2, FAQ Was ich bisher nicht finden konnte, ist eine Aussage dazu, ob die Grid-Off-Steckdose bei Erreichen von MinSoC grundsätzlich abgeschaltet wird, ob sie bei ausreichender PV-Leistung weiter betrieben werden kann, oder ob ein vorhandener Netzanschluss dabei eine Rolle spielt. Zendure liefert auch hier wieder nur spärliche Infos. Viele Details lassen sich daher oft erst durch praktische Erfahrungen und eigene Tests herausfinden. Das war auch bei einigen Fragestellungen in der Vergangenheit so, bei denen ich selbst Messungen und Versuche durchgeführt habe, um das tatsächliche Verhalten der Geräte besser zu verstehen. Daher die Frage an alle: Hat das jemand bereits gezielt getestet? Beispielsweise bei einem SF800 Pro / SF800 Pro 2 mit: aktivem Netzanschluss, Dauerlast an der Grid-Off-Steckdose, MinSoC z. B. 50 %. Was passiert genau, wenn die 50 % erreicht werden und gleichzeitig noch genügend PV-Leistung vorhanden ist? Schaltet die Grid-Off-Steckdose sofort ab? Wird lediglich die Batterie geschont und die Last direkt aus PV versorgt? Oder verhält sich das System noch anders?
  • Hilfe für Skripterstellung mit Blockly

    7k 80k
    7k Themen
    80k Beiträge
    LongbowL
    Ist einiges an Jahren her, aber ich bekomme das auslösen hin, nur wie bekomme ich das dann hin, das ich den Alarm abschalten möchte?
  • Hilfe für Skripterstellung mit Node-RED

    961 13k
    961 Themen
    13k Beiträge
    P
    Der "normale" TCP Request kann auch Rohdaten. Zumindest habe ich darüber damals mit einem Pioneer AVR gesprochen. Den Flow habe ich nicht mehr. Zum Testen / Probieren ein Grundgerüst: Spoiler [ { "id": "telnet_flow_group", "type": "group", "style": { "label": true }, "nodes": [ "inject_trigger", "change_add_newline", "tcp_telnet_request", "debug_response" ], "x": 34, "y": 79, "w": 712, "h": 122 }, { "id": "inject_trigger", "type": "inject", "z": "b59f3d99b19bc9e5", "g": "telnet_flow_group", "name": "Befehl senden", "props": [ { "p": "payload", "v": "help", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 150, "y": 140, "wires": [ [ "change_add_newline" ] ] }, { "id": "change_add_newline", "type": "change", "z": "b59f3d99b19bc9e5", "g": "telnet_flow_group", "name": "Zeilenumbruch (\\r\\n)", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "$msg.payload & \"\\r\\n\"", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 360, "y": 140, "wires": [ [ "tcp_telnet_request" ] ] }, { "id": "tcp_telnet_request", "type": "tcp request", "z": "b59f3d99b19bc9e5", "g": "telnet_flow_group", "server": "localhost", "port": "23", "out": "time", "splitc": "0", "name": "Telnet Server", "ret": "string", "newline": "", "tls": "", "x": 570, "y": 140, "wires": [ [ "debug_response" ] ] }, { "id": "debug_response", "type": "debug", "z": "b59f3d99b19bc9e5", "g": "telnet_flow_group", "name": "Antwort", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 720, "y": 140, "wires": [] } ]
  • Scriptsammlung Vol. 2

    Angeheftet
    3
    3 Stimmen
    3 Beiträge
    5k Aufrufe
    NegaleinN
    Achtung: Diese Scripts sind teils auch ungetestet bzw. nur vom Ersteller getestet worden. Blockly diverse Scripte Schimpfwortgenerator (BananaJoe, Nikolai Radke) Ein Schimpfwortgenerator ioBroker-Forum-Thread: Schimpfwortgenerator Witze aus API (mading) Ein Witzegenerator ioBroker-Forum-Thread: Witzegenerator Bilder mittels LLM ChatGPT Vision ananalysieren (David G.) Bilder mit ChatGPT ananalysieren ioBroker-Forum-Thread: Bilder mittels LLM ChatGPT Vision ananalysieren Visualisierung Agentdvr-Aufnahmen in der Visualisierung darstellen (David G.) Agentdvr-Aufnahmen anzeigen ioBroker-Forum-Thread: Agentdvr-Aufnahmen in der Visualisierung darstellen Trash HTML Widget VIS2 (skvarel) Trash HTML Widget VIS2 ioBroker-Forum-Thread: Trash HTML Widget VIS2 GitHub GitHub
  • Scriptsammlung Vol. 2 -- Diskussion

    Angeheftet
    69
    1 Stimmen
    69 Beiträge
    14k Aufrufe
    NegaleinN
    @Ro75 sagte: Vielen Dank. Ro75. hab es soeben in die Sammlung aufgenommen :)
  • Keylose API für offene Stadtdaten (DWD, Pegel, Strom)

    javascript
    1
    1 Stimmen
    1 Beiträge
    48 Aufrufe
    Niemand hat geantwortet
  • Script NP-Regelung HMS-800-2t (ODTU) + HM 1950AC (KI)

    1
    0 Stimmen
    1 Beiträge
    20 Aufrufe
    Niemand hat geantwortet
  • Alexa Shopping List mit Bring synchronisieren

    184
    0 Stimmen
    184 Beiträge
    44k Aufrufe
    I
    @schiefvancleef danke, eine Umsetzung auf Groß/Klein wäre noch super
  • Heizstab per %-Werte flexibel schalten je nach Einspeisung

    13
    0 Stimmen
    13 Beiträge
    277 Aufrufe
    paul53P
    @rtwl [sagte]: eventuell sind 55° auch schon ausreichend. Davon bin ich überzeugt. Ich habe es im letzten Vorschlag angepasst.
  • mein Kampf mit true und false

    14
    0 Stimmen
    14 Beiträge
    262 Aufrufe
    HomoranH
    @OliverIO sagte: leider ist es bei vis1 so das die meisten datenpunkte immer als string ankommen Ääähm, nein! @OliverIO sagte: egal welcher typ man am datenpunkt konfiguriert hat. Das, ja! Der Typ des DP hat keinen Einfluss auf das Format des Widgets
  • VCF Datei auslesen

    2
    0 Stimmen
    2 Beiträge
    91 Aufrufe
    M
    Thema hat sich erledigt. War am Ende total easy. http://"user":"passwort"@xxx.xxx.xxx.xxx:5000/carddav/"user"/"adressbuch-id"/"kontakt-id".vcf war die Lösung. Jetzt sind auch die Anrufbilder verfügbar.
  • Habe ein Problem in Typescript ....Fehler im Script

    6
    0 Stimmen
    6 Beiträge
    187 Aufrufe
    T
    @OliverIO sagte: @ticaki Allerdings ist es meiner Meinung nach aktuell immer noch so ist, das man Grundlagen der Programmierung kennen muss. Wenn du absolut blank bist, verstehst du nichtmal die Ausgabe der KI und gibst beim 3 Versuch auf. Die Eisntiegshürden sind zwar wirklich gering geworden, aber man muss das auch lernen wollen und auch die prompts richtig formulieren. sonst kommt nur schrott raus. Das stimmt, war mir zuviel arbeit den Text rüber zu kopieren und passend zu formatieren. Umso mehr ahnung man hat umso schneller kommt man als Ziel außer man macht sowas: ❯ lass den quark und gehe es richtig an - setzte agenten darauf an im internet zu suchen wie man das macht und obs überhaupt geht - prüfe die infos und komme dann mit neuen vorschlägen :D
  • Einschaltverzögerung mit schwankenten Werten

    17
    0 Stimmen
    17 Beiträge
    416 Aufrufe
    J
    ich wollte hier keine Verwirrung auslösen, ich bin froh das hier Leute wie ihr bereit sind zu helfen und dann werden die Themen besprochen...Dank geht an Euch!
  • [gelöst] Wie Timer finden?

    10
    0 Stimmen
    10 Beiträge
    354 Aufrufe
    I
    DANKE! Ja, der Bekannte hat das Script (tatsächlich waren es noch 2 weitere verschollene) im Objektbaum javascript gesehen und dort zunächst disabled und gelöscht, und der Timer wird nicht mehr angezeigt. Jetzt warten wir noch 12:12 Uhr ab ;-) (Update: hat geklappt) Ich denke, das war's! Vielen Dank an alle für die freundliche Hilfe, eine kleine Spende für's Projekt geht gleich raus.
  • Mr Pure Salzelektrolyse

    6
    0 Stimmen
    6 Beiträge
    574 Aufrufe
    H
    also, ich habs also geschafft. in die Tuya App hinzugefügt und dann mittels Adapter. Ist allerdings ein bissl eine Spielerei mit dem Developer Account und dem verlinken...aber ich hab alle Daten DANKE
  • Proxmox-Updater (Host/LXC/VM) auch ioBroker,piHole,etc

    58
    3 Stimmen
    58 Beiträge
    12k Aufrufe
    da_WoodyD
    @Bass-T GRANULATION! hab ich schon lange geinstet, echt goil!
  • Daten Seriell von Paradigma Solaranlage lesen

    javascript communication heating
    55
    0 Stimmen
    55 Beiträge
    8k Aufrufe
    Samson71S
    @MatthiasROW Unabhängig davon, dass dieser Beitrag mit über 5 Jahren mehr als steinalt ist........ Schonmal auf der genannten Webseite selber nachgesehen? Nur weil ein (uralter) Link nicht mehr passt, existiert die Webseite und auch deren Inhalte grundsätzlich noch. Ich finde da jedenfalls ne Menge Infos zum Systa Aqua II - Logger incl. der Schaltungsbeschreibung.
  • Ecconreset bei mqtt Teilnehmer

    1
    2
    0 Stimmen
    1 Beiträge
    49 Aufrufe
    Niemand hat geantwortet
  • mqtt-Abruf WiCAN-OBD-Dongle mit mqtt-Adapter und Blockly

    12
    1
    0 Stimmen
    12 Beiträge
    2k Aufrufe
    K
    Hi, Läuft es bei dir noch? Ich bin am überlegen mir auch ein WiCAN-OBD für unseren eUP zu holen. Habe davon aber ehrlich gesagt keine Ahnung. Könntest du mich dann unterstützen? Das wichtigste für mich ist, den aktuellen Akkustand in iobroker zu bekommen. Vielej Dank vorab! :)
  • Ostrom Api auslesen

    4
    0 Stimmen
    4 Beiträge
    721 Aufrufe
    NicolomaN
    ich habe weiter ein anderes: const axios = require('axios'); // ======= OSTROM PROD ======= const CLIENT_ID = 'DEINE_ID'; const CLIENT_SECRET = 'DEIN_SECRET'; const ZIP = '59759'; // ======= INFLUXDB 2.x ======= const INFLUX_URL = 'http://192.168.178.103:8086'; const INFLUX_ORG = 'my_org'; const INFLUX_BUCKET = 'iobroker'; const INFLUX_TOKEN = 'DEIN_TOKEN'; // ======= IO BROKER ======= const BASE_DP = '0_userdata.0.ostrom'; const AUTH_URL = 'https://auth.production.ostrom-api.io/oauth2/token'; const API_URL = 'https://production.ostrom-api.io'; let isRunning = false; createStates(); // API nur selten abrufen schedule('30 14 * * *', fetchPrices); // Status stündlich aktualisieren schedule('0 * * * *', updateCurrentFromCache); // beim Start nur Status aus Cache aktualisieren setTimeout(updateCurrentFromCache, 10000); // manueller API-Abruf on({ id: `${BASE_DP}.control.runNow`, val: true }, async () => { await setStateAsync(`${BASE_DP}.control.runNow`, false, true); await fetchPrices(); }); async function fetchPrices() { if (isRunning) return; const lastFetch = getState(`${BASE_DP}.meta.lastFetch`)?.val || 0; const now = Date.now(); if (now - lastFetch < 120000) { log('Ostrom: Letzte API-Abfrage < 2 Minuten – überspringe', 'warn'); return; } isRunning = true; try { const token = await getAccessToken(); const prices = await getPrices(token); const sorted = prices .slice() .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()); await setStateAsync(`${BASE_DP}.todayTomorrow.json`, JSON.stringify(sorted), true); await updateCurrentFromPrices(sorted); await updateForecast(sorted); await writeToInflux(sorted); await setStateAsync(`${BASE_DP}.meta.lastFetch`, now, true); await setStateAsync(`${BASE_DP}.meta.lastFetchReadable`, new Date(now).toLocaleString('de-DE'), true); log(`Ostrom OK: ${sorted.length} Preise`, 'info'); } catch (err) { if (err.response?.status === 429) { log('Ostrom 429: Rate Limit – später erneut versuchen', 'warn'); } else { log(`Ostrom Fehler: ${err.message}`, 'error'); } if (err.response) { log(`Status: ${err.response.status}`, 'error'); log(JSON.stringify(err.response.data), 'error'); } } finally { isRunning = false; } } async function updateCurrentFromCache() { const json = getState(`${BASE_DP}.todayTomorrow.json`)?.val; if (!json) { log('Ostrom: Kein Preis-Cache vorhanden', 'warn'); return; } try { const prices = JSON.parse(json); await updateCurrentFromPrices(prices); log('Ostrom current.isFree stündlich aktualisiert', 'info'); } catch (err) { log(`Ostrom Cache Fehler: ${err.message}`, 'error'); } } async function updateCurrentFromPrices(prices) { const current = findCurrentPrice(prices); if (!current) return; const grossKwhPrice = Number(current.grossKwhPrice ?? 0); const grossKwhTaxAndLevies = Number(current.grossKwhTaxAndLevies ?? 0); // echter variabler Bruttopreis ohne monatliche Kosten const effectiveGrossKwhPrice = grossKwhPrice + grossKwhTaxAndLevies; await setStateAsync(`${BASE_DP}.current.grossKwhPrice`, round(grossKwhPrice), true); await setStateAsync(`${BASE_DP}.current.grossKwhTaxAndLevies`, round(grossKwhTaxAndLevies), true); await setStateAsync(`${BASE_DP}.current.effectiveGrossKwhPrice`, round(effectiveGrossKwhPrice), true); await setStateAsync(`${BASE_DP}.current.date`, current.date, true); await setStateAsync(`${BASE_DP}.current.dateReadable`, new Date(current.date).toLocaleString('de-DE'), true); await setStateAsync(`${BASE_DP}.current.hour`, new Date(current.date).getHours(), true); await setStateAsync(`${BASE_DP}.current.isFree`, effectiveGrossKwhPrice <= 0, true); } async function updateForecast(prices) { const effectivePrices = prices.map(p => { const gross = Number(p.grossKwhPrice ?? 0); const tax = Number(p.grossKwhTaxAndLevies ?? 0); return { date: p.date, value: gross + tax }; }); const values = effectivePrices.map(p => p.value); const min = Math.min(...values); const max = Math.max(...values); const avg = values.reduce((a, b) => a + b, 0) / values.length; const cheapest = effectivePrices.find(p => p.value === min); const expensive = effectivePrices.find(p => p.value === max); const nextFree = effectivePrices.find(p => new Date(p.date).getTime() >= Date.now() && p.value <= 0); await setStateAsync(`${BASE_DP}.forecast.minEffectiveGrossKwhPrice`, round(min), true); await setStateAsync(`${BASE_DP}.forecast.maxEffectiveGrossKwhPrice`, round(max), true); await setStateAsync(`${BASE_DP}.forecast.avgEffectiveGrossKwhPrice`, round(avg), true); await setStateAsync(`${BASE_DP}.forecast.cheapestDate`, cheapest?.date || '', true); await setStateAsync(`${BASE_DP}.forecast.cheapestDateReadable`, cheapest ? new Date(cheapest.date).toLocaleString('de-DE') : '', true); await setStateAsync(`${BASE_DP}.forecast.mostExpensiveDate`, expensive?.date || '', true); await setStateAsync(`${BASE_DP}.forecast.mostExpensiveDateReadable`, expensive ? new Date(expensive.date).toLocaleString('de-DE') : '', true); await setStateAsync(`${BASE_DP}.forecast.nextFreeDate`, nextFree?.date || '', true); await setStateAsync(`${BASE_DP}.forecast.nextFreeDateReadable`, nextFree ? new Date(nextFree.date).toLocaleString('de-DE') : '', true); await setStateAsync(`${BASE_DP}.forecast.hasFreeHour`, !!nextFree, true); } async function getAccessToken() { const auth = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64'); const res = await axios.post( AUTH_URL, 'grant_type=client_credentials', { headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/x-www-form-urlencoded' }, timeout: 15000 } ); return res.data.access_token; } async function getPrices(token) { const now = new Date(); const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0); const end = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 2, 0, 0, 0); const res = await axios.get(`${API_URL}/spot-prices`, { params: { startDate: start.toISOString(), endDate: end.toISOString(), resolution: 'HOUR', zip: ZIP }, headers: { Authorization: `Bearer ${token}` }, timeout: 15000 }); return res.data.data || []; } async function writeToInflux(prices) { if (!prices.length) return; const lines = []; for (const p of prices) { const ts = BigInt(new Date(p.date).getTime()) * 1000000n; const grossKwhPrice = Number(p.grossKwhPrice ?? 0); const grossKwhTaxAndLevies = Number(p.grossKwhTaxAndLevies ?? 0); const effectiveGrossKwhPrice = grossKwhPrice + grossKwhTaxAndLevies; lines.push( `ostrom_prices,source=production,zip=${escapeTag(ZIP)} ` + `grossKwhPrice=${grossKwhPrice},` + `grossKwhTaxAndLevies=${grossKwhTaxAndLevies},` + `effectiveGrossKwhPrice=${effectiveGrossKwhPrice} ` + `${ts.toString()}` ); } const url = `${INFLUX_URL}/api/v2/write` + `?org=${encodeURIComponent(INFLUX_ORG)}` + `&bucket=${encodeURIComponent(INFLUX_BUCKET)}` + `&precision=ns`; await axios.post(url, lines.join('\n'), { headers: { Authorization: `Token ${INFLUX_TOKEN}`, 'Content-Type': 'text/plain' }, timeout: 15000 }); } function findCurrentPrice(prices) { const now = new Date(); return prices.find(p => { const start = new Date(p.date); const end = new Date(start.getTime() + 3600000); return now >= start && now < end; }); } async function createStates() { await ensure(`${BASE_DP}.control.runNow`, 'boolean', true, true, 'button'); await ensure(`${BASE_DP}.meta.lastFetch`, 'number', 0, true, 'value'); await ensure(`${BASE_DP}.meta.lastFetchReadable`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.todayTomorrow.json`, 'string', '', true, 'json'); await ensure(`${BASE_DP}.current.grossKwhPrice`, 'number', 0, true, 'value', 'ct/kWh'); await ensure(`${BASE_DP}.current.grossKwhTaxAndLevies`, 'number', 0, true, 'value', 'ct/kWh'); await ensure(`${BASE_DP}.current.effectiveGrossKwhPrice`, 'number', 0, true, 'value', 'ct/kWh'); await ensure(`${BASE_DP}.current.date`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.current.dateReadable`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.current.hour`, 'number', 0, true, 'value', 'h'); await ensure(`${BASE_DP}.current.isFree`, 'boolean', false, true, 'indicator'); await ensure(`${BASE_DP}.forecast.minEffectiveGrossKwhPrice`, 'number', 0, true, 'value', 'ct/kWh'); await ensure(`${BASE_DP}.forecast.maxEffectiveGrossKwhPrice`, 'number', 0, true, 'value', 'ct/kWh'); await ensure(`${BASE_DP}.forecast.avgEffectiveGrossKwhPrice`, 'number', 0, true, 'value', 'ct/kWh'); await ensure(`${BASE_DP}.forecast.cheapestDate`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.forecast.cheapestDateReadable`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.forecast.mostExpensiveDate`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.forecast.mostExpensiveDateReadable`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.forecast.nextFreeDate`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.forecast.nextFreeDateReadable`, 'string', '', true, 'text'); await ensure(`${BASE_DP}.forecast.hasFreeHour`, 'boolean', false, true, 'indicator'); } async function ensure(id, type, def, write, role, unit = '') { const exists = await existsStateAsync(id); if (!exists) { await createStateAsync(id, def, { type, role, read: true, write, unit }); } } function round(value) { return Math.round(value * 1000) / 1000; } function escapeTag(value) { return String(value) .replace(/ /g, '\\ ') .replace(/,/g, '\\,') .replace(/=/g, '\\='); }
  • [Vorlage] Anwesenheitssimulation mit dauerhaftem Lernen

    javascript template security
    21
    1 Stimmen
    21 Beiträge
    1k Aufrufe
    NashraN
    @mrMuppet Danke für die gute Erklärung
  • verschiedene Skripte

    javascript
    1
    1
    0 Stimmen
    1 Beiträge
    127 Aufrufe
    Niemand hat geantwortet
  • [Vorlage] Luftqualitätswerte abrufen

    55
    2
    4 Stimmen
    55 Beiträge
    9k Aufrufe
    Siggi0904S
    @Boronsbruder sagte: Wenn ich mal Zeit habe, schau ich mir APIv4 an ;) Wenn man in die News zur V4 schaut, sind "nur" Statistiken dazu gekommen. Ich habe bei mir auf die V4 mit den aktuellen Einstellungen umgestellt und es funktioniert bisher. Vielleicht kann man das Script noch ausbauen und weitere Funktionen der API implementieren. Danke und frohe Ostern.

556

Online

32.9k

Benutzer

83.2k

Themen

1.3m

Beiträge