Skip to content

Skripten / Logik

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

16.5k Themen 213.3k Beiträge

NEWS

Unterkategorien


  • Hilfe für Skripterstellung mit JavaScript

    2k 49k
    2k Themen
    49k Beiträge
    R
    hier noch etwas überarbeitet und ohne Warnungen // version: 0.2.6 ////////////////////////////////////////////////// const locationName = 'wo auch immer'; ////////////////////////////////////////////////// // Schriftgrößen-Konfiguration const fontSizeCurrentLabel = '1.3rem'; const fontSizeTempBig = '3.8rem'; const fontSizeDescription = '1.1rem'; const fontSizeInfoGrid = '0.85rem'; const fontSizeSunMoon = '0.8rem'; const fontSizeHourly = '0.75rem'; const fontSizeHourlyRain = '0.65rem'; const fontSizeForecastDay = '0.75rem'; const fontSizeForecastText = '0.65rem'; const fontSizeForecastTempMax = '1rem'; const fontSizeForecastTempMin = '0.85rem'; const fontSizeForecastDetails = '0.65rem'; const version = '0.2.6'; const dpBase = 'open-meteo-weather.0.' + locationName + '.weather'; const forecast = dpBase + '.forecast'; const targetDP = '0_userdata.0.Wetter_Widget_HTML'; // Sprach-Check let sysLang = 'de'; try { const systemConfig = getObject("system.config"); sysLang = systemConfig.common.language || 'de'; } catch (e) { sysLang = 'de'; } const i18n = { de: { current: "Aktuell" }, en: { current: "Current" } }; const lang = i18n[sysLang] || i18n['en']; // DP anlegen falls nicht vorhanden if (!existsState(targetDP)) { createState(targetDP, '', { name: 'Weather Widget for VIS', type: 'string', role: 'html' }); } // ------------------------------------------------------------ // Hilfsfunktionen // ------------------------------------------------------------ // HEUTE aus JavaScript, kompakt function getToday() { const d = new Date(); const day = String(d.getDate()).padStart(2, "0"); const month = String(d.getMonth() + 1).padStart(2, "0"); const year = d.getFullYear(); return `${day}.${month}.${year}`; } function getVal(id, unit = "") { if (!existsState(id)) return "--" + unit; let state = getState(id); if (!state || state.val === null || state.val === undefined) return "--" + unit; return state.val + unit; } function getImg(id, size = "20px") { if (!existsState(id)) return ""; let state = getState(id); if (!state || !state.val) return ""; return `<img src="${state.val}" style="width:${size}; height:${size}; object-fit:contain;">`; } function getNum(id) { let s = getState(id); return (!s || s.val === null || s.val === undefined) ? null : Number(s.val); } function getSunHours(id) { let sec = getNum(id); if (sec === null) return "--h"; return (sec / 3600).toFixed(1) + "h"; } // ------------------------------------------------------------ // Hauptfunktion // ------------------------------------------------------------ function updateWeatherWidget() { // ⭐ AB HIER: ALLES UNVERÄNDERT GELASSEN let html = ` <style> @keyframes moonGlow { 0% { filter: drop-shadow(0 0 2px #fbbf24); opacity: 0.85; } 50% { filter: drop-shadow(0 0 6px #fbbf24); opacity: 1; } 100% { filter: drop-shadow(0 0 2px #fbbf24); opacity: 0.85; } } .moon-anim { animation: moonGlow 3.5s ease-in-out infinite; } .w-container { font-family: 'Segoe UI', sans-serif; background: linear-gradient(160deg, #1e293b 0%, #0f172a 100%); color: #f1f5f9; padding: 10px; border-radius: 20px; border: 1px solid #334155; box-shadow: 0 10px 30px rgba(0,0,0,0.5); } .w-header { display: grid; grid-template-columns: 1.2fr 1.5fr 1fr; gap: 10px; background: rgba(255,255,255,0.05); padding: 10px; border-radius: 10px; margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.1); } .w-temp-big { font-size: ${fontSizeTempBig}; font-weight: 900; color: #fbbf24; line-height: 1; } .w-desc { font-size: ${fontSizeDescription}; color: #38bdf8; font-weight: 600; } .w-info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: ${fontSizeInfoGrid}; margin-top: 10px; } .w-info-item { background: rgba(0,0,0,0.2); padding: 6px 10px; border-radius: 10px; display: flex; align-items: center; gap: 5px; } .w-sun-moon { font-size: ${fontSizeSunMoon}; line-height: 1.6; border-left: 1px solid rgba(255,255,255,0.1); padding-left: 15px; } .w-hourly { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; margin-bottom: 10px; background: rgba(0,0,0,0.15); padding: 10px; border-radius: 15px; } .w-h-item { text-align: center; font-size: ${fontSizeHourly}; } .w-h-time { font-weight: bold; color: #38bdf8; } .w-h-temp { font-weight: bold; color: #fbbf24; display: block; } .w-h-rain { font-size: ${fontSizeHourlyRain}; color: #94a3b8; } .w-forecast { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; } .w-fc-day { background: rgba(255,255,255,0.03); padding: 12px 8px; border-radius: 18px; text-align: center; border: 1px solid rgba(255,255,255,0.05); display: flex; flex-direction: column; justify-content: space-between; } .w-fc-name { font-weight: bold; color: #38bdf8; font-size: ${fontSizeForecastDay}; text-transform: uppercase; margin-bottom: 2px; } .w-fc-text { font-size: ${fontSizeForecastText}; color: #94a3b8; min-height: 2.2em; display: flex; align-items: center; justify-content: center; text-align: center; margin-bottom: 5px; } .w-fc-temp-max { color: #f87171; font-weight: bold; font-size: ${fontSizeForecastTempMax}; display: block; text-align: center; } .w-fc-temp-min { color: #60a5fa; font-size: ${fontSizeForecastTempMin}; display: block; margin-bottom: 5px; text-align: center; } .w-fc-day img { margin: 2px 0 4px 0; } .w-fc-details { font-size: ${fontSizeForecastDetails}; color: #94a3b8; border-top: 1px solid rgba(255,255,255,0.05); margin-top: 8px; padding-top: 8px; } </style> <div class="w-container"> <div class="w-header"> <div style="text-align: center;"> <div style="font-size:${fontSizeCurrentLabel}; font-weight:bold;"> ${lang.current} / ${getVal(forecast + '.day0.name_day')} </div> <div style="font-size:0.75rem; color:#94a3b8; margin-top:0;"> ${getToday()} </div> ${getImg(dpBase + '.current.icon_url', "80px")} <div class="w-desc">${getVal(dpBase + '.current.weather_text')}</div> </div> <div> <div class="w-temp-big">${getVal(dpBase + '.current.temperature_2m', " °C")}</div> <div style="font-weight:bold; margin-bottom:10px;"> <span style="color:#f87171">${getVal(forecast + '.day0.temperature_2m_max', " °C")}</span> | <span style="color:#60a5fa">${getVal(forecast + '.day0.temperature_2m_min', " °C")}</span> </div> <div class="w-info-grid"> <div class="w-info-item">💧 ${getVal(dpBase + '.current.relative_humidity_2m', "%")}</div> <div class="w-info-item">🌧️ ${getVal(forecast + '.day0.precipitation_sum', "mm")}</div> <div class="w-info-item">☀️ ${getSunHours(forecast + '.day0.sunshine_duration')}</div> <div class="w-info-item">☁️ ${getVal(dpBase + '.current.cloud_cover', "%")}</div> <div class="w-info-item">💨 Wind ${getVal(dpBase + '.current.wind_speed_10m', " km/h")}</div> <div class="w-info-item">🌬️ Böen ${getVal(dpBase + '.current.wind_gusts_10m', " km/h")}</div> </div> </div> <div class="w-sun-moon" style="position:relative;"> 🌅 ${getVal(forecast + '.day0.sunrise')}<br> 🌇 ${getVal(forecast + '.day0.sunset')}<br> 🌙 ${getVal(forecast + '.day0.moonrise')}<br> 🌘 ${getVal(forecast + '.day0.moonset')}<br> <div style="margin-top:6px;"> ${getImg(forecast + '.day0.moon_phase_icon', "34px")} <div class="moon-anim" style="font-size:0.75rem; color:#cbd5e1;"> ${getVal(forecast + '.day0.moon_phase_text')} </div> </div> <div style="margin-top:10px;"> 💨 Richtung: ${getVal(dpBase + '.current.wind_direction_text')}<br> ${getImg(dpBase + '.current.wind_direction_icon', "30px")} </div> <div style="position:absolute; bottom:-10px; right:0; font-size:0.6rem; color:#475569; opacity:0.8;"> Script Version ${version} </div> </div> </div> <div class="w-hourly"> `; // Stunden – mit Wind + Mond for (let h = 0; h <= 5; h++) { let hPath = forecast + '.hourly.next_hours.hour' + h; let isNight = getNum(hPath + '.is_day') === 0; html += ` <div class="w-h-item"> <div class="w-h-time">${getVal(hPath + '.time')}</div> ${getImg(hPath + '.icon_url', "30px")} <span class="w-h-temp">${getVal(hPath + '.temperature_2m', " °C")}</span> <span class="w-h-rain"> 🌧️${getVal(hPath + '.precipitation_probability', "%")} / ${getVal(hPath + '.precipitation', "mm")} </span> <div style="margin-top:4px; font-size:0.7rem; color:#cbd5e1;"> 💨 ${getVal(hPath + '.wind_speed_10m', " km/h")} 🌬️ ${getVal(hPath + '.wind_gusts_10m', " km/h")} </div> <div style="margin-top:2px;"> ${getImg(hPath + '.wind_direction_icon', "32px")} <span style="font-size:0.7rem; color:#94a3b8;"> ${getVal(hPath + '.wind_direction_text')} </span> </div> ${ isNight ? ` <div style="margin-top:4px;"> ${getImg(hPath + '.moon_phase_icon', "24px")} <div style="font-size:0.65rem; color:#cbd5e1;"> ${getVal(hPath + '.moon_phase_text')} </div> </div> ` : "" } </div> `; } html += ` </div> <div class="w-forecast"> `; // 6-Tage-Vorhersage for (let i = 1; i <= 6; i++) { let d = forecast + '.day' + i; html += ` <div class="w-fc-day"> <div> <div class="w-fc-name">${getVal(d + '.name_day')}</div> <div class="w-fc-text">${getVal(d + '.weather_text')}</div> ${getImg(d + '.icon_url', "50px")} <span class="w-fc-temp-max">${getVal(d + '.temperature_2m_max', " °C")}</span> <span class="w-fc-temp-min">${getVal(d + '.temperature_2m_min', " °C")}</span> </div> <div class="w-fc-details"> 🌧️ ${getVal(d + '.precipitation_sum', "mm")} (${getVal(d + '.precipitation_probability_max', "%")})<br> 💧 ${getVal(d + '.relative_humidity_2m_mean', "%")}<br> 💨 Wind ${getVal(d + '.wind_speed_10m_max', " km/h")}<br> 🌬️ Böen ${getVal(d + '.wind_gusts_10m_max', " km/h")}<br> ${getVal(d + '.wind_direction_text')}<br> ${getImg(d + '.wind_direction_icon', "32px")}<br> ${getImg(d + '.wind_gust_icon', "24px")}<br> ☀️ ${getSunHours(d + '.sunshine_duration')} </div> </div> `; } html += `</div></div>`; setState(targetDP, html, true); console.log("Weather widget: HTML successfully generated (v0.2.6-XYZ-SUN-CLOUD-C-DATE-COMPACT)."); } // Trigger updateWeatherWidget(); schedule("*/5 * * * *", updateWeatherWidget); on({id: dpBase + '.current.temperature_2m', change: 'any'}, updateWeatherWidget); on({id: forecast + '.hourly.next_hours.hour0.time', change: 'any'}, updateWeatherWidget); [image: 1770566801260-43377c6a-c836-4580-8f67-56ca3bac553b-image.png]
  • Hilfe für Skripterstellung mit Blockly

    7k 79k
    7k Themen
    79k Beiträge
    AsgothianA
    Ich denke in deinem Fall greift diese Lösung nicht. Die Lösung ist den Baustein [image: 1770589884460-screenshot-2026-02-08-at-23.31.01.png] durch das folgende Konstrukt zu ersetzen: [image: 1770590133517-screenshot-2026-02-08-at-23.35.29.png] Zusätzlich muss vor jeder anderen Ansteuerung der Aussenlampe Ecke ein [image: 1770590157266-screenshot-2026-02-08-at-23.35.55.png] gesetzt werden. A.
  • Hilfe für Skripterstellung mit Node-RED

    953 13k
    953 Themen
    13k Beiträge
    S
    welche Palette hast du installiert, damit du den "AND" Baustein hast?
  • [Vorlage] Blockly heute/morgen frei zur Rollo-/Heizungsst.

    Verschoben blockly template
    24
    2
    1 Stimmen
    24 Beiträge
    6k Aufrufe
    rantanplanR
    @hotspot_2 sagte in [Vorlage] Blockly heute/morgen frei zur Rollo-/Heizungsst.: Hallo zusammen, ich habe bei mir dieses Skript auch installiert, und die Variable "morgen_frei" wird nicht initialisiert automatisch. Inititiert man die Variable z.B. manuell dann funktioniert das Skript einwandfrei aus meiner Sicht. Würde es Sinn machen es so abzuändern: [image: 1664278883252-1e2379d8-f8ca-4c85-a586-2ecfeeed8916-image.png] Ich meine das sollte hinhauen auch wenn morgen dann ein freier Tag wäre sollte der dann richtig gesetzt werden. Was meint ihr? Kann man so machen. Habe ich "damals" wohl übersehen. Ich würde die Abfrage eventuell ausserhalb des Triggers machen. Dann wird es nur einmal beim Script-Start ausgeführt. (Sorry für's aus der Versenkung holen, ich finde das Skript aber echt gut für einige Anwendungsfälle). Schön dass es gefällt :blush: Grüße
  • Skript für Klima funktioniert nicht.

    7
    3
    0 Stimmen
    7 Beiträge
    654 Aufrufe
    A
    @paul53 Super, guter Hinweis. Cool. Danke.
  • Skript ändert Logik bei Uhrzeitenwechsel nicht

    26
    1
    0 Stimmen
    26 Beiträge
    2k Aufrufe
    Z
    @paul53 kaum isit die Logangabe drin, läuft es. Komisch :dart: Wobei ich die Zeit auch auf 5 sek verkürzt habe. Werde die Tage noch einmal testen. Danke!!
  • Homematic Heizkörperthermostate gehen in Auto-Modus

    9
    0 Stimmen
    9 Beiträge
    503 Aufrufe
    Jens KatheJ
    @david-g Der Spaß es selbst zu machen ;-)
  • [Vorlage] Multi Ereignislisten Skript

    Verschoben javascript template
    112
    3 Stimmen
    112 Beiträge
    24k Aufrufe
    Martin BlankM
    @liv-in-sky Wow das nenn ich mal eine sehr gute Erklärung da. Ok dann werde ich es weiter mit dem Adapter versuch.
  • time-switch Adapter / Bedingung

    1
    0 Stimmen
    1 Beiträge
    199 Aufrufe
    Niemand hat geantwortet
  • Iframe2Image

    3
    0 Stimmen
    3 Beiträge
    328 Aufrufe
    H
    @djmarc75 VIelen DANK :-)
  • Skript schaltet selber um, obwohl Bedinung nicht vorhanden.

    5
    1
    0 Stimmen
    5 Beiträge
    179 Aufrufe
    S
    @dr-bakterius Ok werde ich mal testen ob das besser funktioniert.
  • HTTP API Doorbird was läuft hier falsch.

    13
    0 Stimmen
    13 Beiträge
    1k Aufrufe
    B
    @mcu Lääääuft !!!!!!! Danke Danke Danke DANKE !
  • Shelly1 mit Shelly Motion und Alexa verbinden?

    1
    0 Stimmen
    1 Beiträge
    251 Aufrufe
    Niemand hat geantwortet
  • Aus History Adapter Mittelwert erhalten

    javascript
    4
    0 Stimmen
    4 Beiträge
    625 Aufrufe
    Andre WippichA
    Danke Euch!
  • Blockly: auf Werte einer Liste zugreifen

    blockly
    24
    1
    0 Stimmen
    24 Beiträge
    12k Aufrufe
    Stephan SchleichS
    @paul53 Danke Paul, 1 Sekunde Pause direkt nach dem Trigger hat das Problem gelöst, sehr komisch und unverständlich für mich, aber läuft wieder :+1:
  • MQTT get und set anlegen für zigbee2mqtt

    8
    0 Stimmen
    8 Beiträge
    1k Aufrufe
    Q
    da ich bei mir die einzelnen attribute und kein komplettes json ausgeben lasse, hat mir das hier nicht wirklich weitergeholfen, aber schon ein wenig inspiriert. hier mal mein erster schnellschuss - bisher funktioniert alles, kann aber sicher noch etwas verbessert werden (datentyp, min/max-werte): const mqtt = "mqtt.0"; const topic = "zigbee2mqtt"; const zigbee2mqtt = mqtt +"."+ topic; const doNotGenerateSetStates = ["update-state", "availability", "linkquality"] const doNotOverwriteExistingObjects = false; var devices = JSON.parse(getState(zigbee2mqtt +".bridge.devices").val); devices.forEach(device => { if (device.friendly_name.length > 0) { var device_name = device.friendly_name.replaceAll("/", ".") console.log(device_name) //console.log({device}) if (device.type.toLowerCase() === "router") { console.log("ist router") var datapointBase = zigbee2mqtt + "." + device_name; if (existsObject(datapointBase)) { console.log(datapointBase + " existiert") var getPoints = $('[state.id=' + datapointBase + '.*]') //console.log({getPoints}) getPoints.each(function (id, i) { if (existsObject(id)) { var attribute = id.split('.').pop(); if (doNotGenerateSetStates.includes(attribute.toLocaleLowerCase())) { console.log("--ABBRUCH: " + attribute) return; } var setMqttPath = topic + "/" + device.friendly_name + "/set/" + attribute; var setId = datapointBase + ".set." + attribute; if (existsObject(setId) && doNotOverwriteExistingObjects) { console.log("--ABBRUCH (existiert bereits): " + attribute) return; } var attributeSpecs = device.definition.exposes.find(data => data.hasOwnProperty('features')).features.find(data => data.name === attribute); if (attributeSpecs === undefined) { attributeSpecs = device.definition.exposes.find(data => data.name === attribute); } //console.log(attributeSpecs) var getObj = getObject(id); getObj._id = setId; getObj.common.name = setMqttPath; getObj.native.topic = setMqttPath; if (attributeSpecs?.value_min != undefined) { getObj.common.min = attributeSpecs.value_min; } if (attributeSpecs?.value_max != undefined) { getObj.common.max = attributeSpecs.value_max; } if (attributeSpecs?.unit != undefined) { getObj.common.unit = attributeSpecs.unit; } setObject(setId, getObj, function (err) { if (err) console.error('Cannot write object: ' + err); }); console.log(setId) } }); } } } }) und das ergebnis: [image: 1663745698723-11798552-73cb-4280-a4da-507c4819625f-image.png] edit: ich war etwas ungehalten und habe min, max und unit schon hinzugeügt. mehr werte kann man ja bei bedarf analog dazu auslesen. als nächstes kommt dann noch ein alias datenpunkt, der entsprechend read und write datenpunkte vereint.
  • [gelöst]Zufällige Zahl generieren

    19
    1
    0 Stimmen
    19 Beiträge
    490 Aufrufe
    J
    @paul53 das wars!Perfekt! Danke Dir! Schade, dass ich es nicht verstehe aber trotzdem vielen Dank dafür! Liebe Grüße Jürgen
  • Homatik Ip Heizkörper Thermostat

    17
    1
    0 Stimmen
    17 Beiträge
    1k Aufrufe
    paul53P
    @raspberrypi sagte: Ich weiss Gloss nicht ob sowas überhaupt geht ??? Funktioniert das Skript nicht? Vorher natürlich erst den Datenpunkt für den Mittelwert erstellen! Dann nach Skriptstart warten, bis ein Ventil seine Position ändert.
  • Zeitstempel in Homematic Systemvariable als Uhrzeit

    14
    1
    0 Stimmen
    14 Beiträge
    1k Aufrufe
    paul53P
    @alf4711 Damit kann niemand etwas anfangen. Exportiere mal das Blockly und poste den Export in Code tags (oben </>).
  • PRTG mit WLED status meldung

    1
    0 Stimmen
    1 Beiträge
    92 Aufrufe
    Niemand hat geantwortet
  • [gelöst] Edimax WLAN Steckdose schalten

    Verschoben
    13
    0 Stimmen
    13 Beiträge
    4k Aufrufe
    S
    @hg6806 Ich bin der Anleitung https://github.com/mwittig/edimax-smartplug/issues/17 gefolgt und der Befehl im telnet "nvc all" hat dann auch so infos Run.FW.Version=3.00c oder Device.Configuration.HW.ModelName=SP2101W_V2 ... diese Werte sind von mir natürlich... Das Passwort so herausfinden ist sehr mühsam - aber muss man ja nur einmal machen.... Das ganze per "curl" abholen ist da schon schlimmer. Ich verwende gerade den Adapter "linux-control" um den curl Befehl auf einem SSH server auszuführen - ich hoffe es gibt bald eine bessere Möglichkeit. Ich habe aber weder einen EdiMax Adapter, noch einen einfachen HTTP adapter gefunden der dieses XML schicken und parsen könnte.
  • [Script] Eieruhr

    Verschoben javascript
    21
    0 Stimmen
    21 Beiträge
    6k Aufrufe
    K
    erledigt.
  • on -> scriptEnabled -> Error im log

    javascript
    19
    0 Stimmen
    19 Beiträge
    356 Aufrufe
    GlasfaserG
    @bahnuhr sagte in on -> scriptEnabled -> Error im log: Hatte alle deaktiviert und dann immer 10-20 aktiviert. Script laufen lassen. keine Fehler. Und dann wieder 10-20 aktiviert, Scirpt laufen lassen. Bis ich fertig war. Ja ... auch OK. Aber ich meinte ... eventuell in einen Script ein schedule der nicht richtig erstellt wurde , was dir so nicht erstmal auffällt . Deshalb sollteste du in der JS Suchfunktion alle Scripte mit "schedule" Anzeigen lassen/durchsuchen. Aber wenn es jetzt wieder geht , dann ist es ja gut.

420

Online

32.6k

Benutzer

82.3k

Themen

1.3m

Beiträge