Weiter zum Inhalt

Visualisierung

9.5k Themen 104.4k Beiträge

Hilfe zu Visualisierungen

NEWS

  • VIS1: Vis aktualisiert Bilder nicht mehr

    14
    0 Stimmen
    14 Beiträge
    602 Aufrufe
    madingM
    Guten Morgen, endlich habe ich Zeit gefunden, mich damit weiter zu beschäftigen. Eine Suche nach writeFile brachte mich auf folgendes Thema. Nun läuft folgendes JS in einem cron Trigger in Blockly. var fs = require('fs'); const picture= fs.readFileSync('/opt/iobroker/iobroker-data/files/vis.0/main/img/webuntis-screenshot.png'); //liest linux-datei-system writeFile('vis.0','/main/img/webuntis-screenshot.png', picture, function (error) { }); //schreibt in iobroker system Funktioniert, danke, auch an @liv-in-sky für seine super dokumentierte Lösung!
  • VIS2 Inventwo HTML tags in Tabelle

    7
    2
    0 Stimmen
    7 Beiträge
    200 Aufrufe
    fuzzy1955F
    @skvarel sagte in VIS2 Inventwo HTML tags in Tabelle: hier geht es aber um inventwo Pardon ... das hab ich übersehen.
  • Material Design Widgets: Calendar Widget

    vis
    201
    2
    5 Stimmen
    201 Beiträge
    41k Aufrufe
    WG25W
    Moin, ist das Kalender Widget auch unter vis2 anwendbar? Ich kann es einbinden und die Termine werden auch angezeigt. Allerdings sind die Überschriften alle in englisch. Wo muss ich da was anpassen?
  • vis basic image aktualisiert sich nicht

    7
    5
    0 Stimmen
    7 Beiträge
    140 Aufrufe
    HomoranH
    @mading ich hab mal für dich gesucht. https://forum.iobroker.net/post/1265085 das müsste passen. Allerdings mit javascript!
  • Energiefluss-Erweitert Ansichten

    59
    1 Stimmen
    59 Beiträge
    15k Aufrufe
    skvarelS
    Als Popup [image: 1773676766859-fb5634c4-317a-4de7-a6bb-d5989dc8d284-image.png]
  • Google Material 3 / Material You - Vis2

    vis material css
    11
    7
    3 Stimmen
    11 Beiträge
    474 Aufrufe
    M
    Hier die Einstellungen: Was macht dieses Skript? Dieses Skript generiert ein komplettes Einstellungs-Menü (Setup-Tab) im Material 3 Design für euer vis-Dashboard. Es rendert sauberes HTML und bringt drei Hauptfunktionen mit: System & Automatiken: Eine elegante Listenansicht mit Schaltern, um z.B. Skripte (Rollladenautomatik, Urlaubsmodus) ein- und auszuschalten. Graphen-Filter (Chips): Interaktive Buttons (Chips), mit denen man Datenpunkte für ein Diagramm (z.B. Heizung) ein- und ausblenden kann. Dynamische Wallpaper-Auswahl: Das absolute Highlight! Das Skript liest einen festgelegten Ordner eures ioBrokers aus und generiert automatisch ein Popup-Menü mit allen darin enthaltenen Bildern (.jpg, .png, .webp). Wählt ihr ein Bild aus, wird der Pfad in einen Datenpunkt geschrieben (perfekt für die Kombination mit meinem "M3 Theme Master" Skript). Was muss vorbereitet werden? Damit das Skript auf euren ioBroker-Dateispeicher zugreifen darf, müsst ihr einen wichtigen Haken setzen: Geht in die Instanz-Einstellungen eures JavaScript-Adapters. Setzt den Haken bei "Erlaube das Kommando exec" (falls noch nicht geschehen) und tragt unter Zusätzliche NPM-Module das Modul fs ein, falls es dort nicht standardmäßig aktiv ist. Alternativ reicht es oft schon, in den JS-Adapter-Einstellungen den Haken bei "Erlaube Zugriff auf Dateisystem" zu setzen. Wallpaper-Ordner: Legt im ioBroker Dateimanager (unter vis.0 oder vis-2.0) einen Ordner an und ladet dort ein paar Bilder hoch. Passt den Pfad im Skript (WALLPAPER_WEB_DIR) entsprechend an. Eure Geräte eintragen: Schaut im Skript in die Funktion getListItems(). Dort tragt ihr einfach die Datenpunkte eurer eigenen ioBroker-Skripte oder Schalter ein. Wie wendet man das an? Das Skript erstellt alle nötigen Datenpunkte automatisch (standardmäßig unter 0_userdata.0.dashboard.). Startet das Skript. Zieht ein "Basic - String" (oder "Basic - HTML") Widget in eure vis. Tragt unter HTML / Inhalt den Datenpunkt-Namen in geschweiften Klammern ein: {0_userdata.0.dashboard.setupHTML} Zieht das Widget so groß wie nötig, das Skript bringt eine eigene, stylische M3-Scrollbar mit, falls der Platz nicht reicht. Das Skript (TypeScript) // ============================================================ // renderSetup — M3 Material You Styling (Kompakt & Robust-Scroll) // ============================================================ const fs = require('fs'); // === KONFIGURATION ========================================================== const BASE_PATH = '0_userdata.0.dashboard'; const DP_SETUP_HTML = `${BASE_PATH}.setupHTML`; const DP_IMAGE_PATH = `${BASE_PATH}.themeImagePath`; const DP_PRIVACY = `${BASE_PATH}.privacyMode`; // GRAPHEN-FILTER (Beispiele für eine Heizungs-Ansicht) const DP_CHART_BRENNER = `${BASE_PATH}.chartShowBrenner`; const DP_CHART_VALVE = `${BASE_PATH}.chartShowValve`; const DP_CHART_ACT = `${BASE_PATH}.chartShowAct`; const DP_CHART_SET = `${BASE_PATH}.chartShowSet`; const DP_CHART_WINDOW = `${BASE_PATH}.chartShowWindow`; const DP_CHART_HUMID = `${BASE_PATH}.chartShowHumid`; // ORDNER FÜR DIE HINTERGRUNDBILDER // Wichtig: Der Ordner muss im ioBroker Dateimanager existieren! const WALLPAPER_WEB_DIR = '/vis-2.0/Material_You/img/wallpaper/'; const WALLPAPER_SYS_DIR = '/opt/iobroker/iobroker-data/files' + WALLPAPER_WEB_DIR; // ============================================================================ // === AB HIER NUR ANPASSEN, WENN EIGENE LISTEN-EINTRÄGE GEWÜNSCHT SIND === // ============================================================================ const M3 = { primary: 'var(--m3-primary)', onPrimary: 'var(--m3-on-primary)', primaryContainer: 'var(--m3-primary-container)', onPrimaryContainer: 'var(--m3-on-primary-container)', surfaceContainerLow: 'var(--m3-surface-container-low)', surfaceContainerHighest:'var(--m3-surface-container-highest)', surfaceVariant: 'var(--m3-surface-variant)', onSurface: 'var(--m3-on-surface)', onSurfaceVariant: 'var(--m3-on-surface-variant)', outline: 'var(--m3-outline)', outlineVariant: 'var(--m3-outline-variant)' }; const ICONS: Record<string, string> = { 'party': 'M2 22l5-14 9 9-14 5zm3.3-3.3l7.05-2.5-4.55-4.55-2.5 7.05zM14.55 12.55l-1.05-1.05 5.6-5.6q.8-.8 1.925-.8t1.925.8l.6.6-1.05 1.05-.6-.6q-.35-.35-.875-.35t-.875.35l-5.6 5.6zM10.55 8.55l-1.05-1.05.6-.6q.35-.35.35-.85t-.35-.85l-.65-.65 1.05-1.05.65.65q.8.8.8 1.9t-.8 1.9l-.6.6zm2 2l-1.05-1.05 3.6-3.6q.35-.35.35-.875t-.35-.875l-1.6-1.6 1.05-1.05 1.6 1.6q.8.8.8 1.925t-.8 1.925l-3.6 3.6zm4 4l-1.05-1.05 1.6-1.6q.8-.8 1.925-.8t1.925.8l1.6 1.6-1.05 1.05-1.6-1.6q-.35-.35-.875-.35t-.875.35l-1.6 1.6z', 'guests': 'M16 11C17.66 11 18.99 9.66 18.99 8C18.99 6.34 17.66 5 16 5C14.34 5 13 6.34 13 8C13 9.66 14.34 11 16 11M8 11C9.66 11 10.99 9.66 10.99 8C10.99 6.34 9.66 5 8 5C6.34 5 5 6.34 5 8C5 9.66 6.34 11 8 11M8 13C5.67 13 1 14.17 1 16.5V19H15V16.5C15 14.17 10.33 13 8 13M16 13C15.71 13 15.38 13.02 15.03 13.05C16.19 13.89 17 15.02 17 16.5V19H23V16.5C23 14.17 18.33 13 16 13Z', 'sun': 'M20 14H18L14.8 23H16.7L17.4 21H20.6L21.3 23H23.2L20 14M17.8 19.7L19 16L20.2 19.7H17.8M7 9H15V11H7V9M7 12H15V14H7V12M7 15H15V16.5L14.8 17H7V15M13.7 20H7V18H14.5L13.7 20M16 8H6V20H4V8H2V4H20V8H18V12H16.6L16.1 13.3L16 13.7V8Z', 'alarm': 'M12 20A7 7 0 0 1 5 13A7 7 0 0 1 12 6A7 7 0 0 1 19 13A7 7 0 0 1 12 20M12 4A9 9 0 0 0 3 13A9 9 0 0 0 12 22A9 9 0 0 0 21 13A9 9 0 0 0 12 4M7.88 3.39L6.6 1.86L2 5.71L3.29 7.24L7.88 3.39M22 5.72L17.4 1.86L16.11 3.39L20.71 7.25L22 5.72M12.5 8H11V14L15.75 16.85L16.5 15.62L12.5 13.25V8Z', 'person': 'M12 4A4 4 0 0 1 16 8A4 4 0 0 1 12 12A4 4 0 0 1 8 8A4 4 0 0 1 12 4M12 14C16.42 14 20 15.79 20 18V20H4V18C4 15.79 7.58 14 12 14Z', 'moon': 'M12 21q-3.75 0-6.375-2.625T3 12q0-3.75 2.625-6.375T12 3q.35 0 .688.025t.662.075q-1.025.725-1.637 1.888T11.1 7.5q0 2.25 1.575 3.825T16.5 12.9q1.375 0 2.525-.612t1.875-1.638q.05.325.075.663T21 12q0 3.75-2.625 6.375T12 21Zm0-2q2.2 0 3.95-1.212T18.5 14.625q-.5.125-1 .2t-1 .075q-3.075 0-5.238-2.162T9.1 7.5q0-.5.075-1t.2-1q-1.95.8-3.162 2.55T5 12q0 2.9 2.05 4.95T12 19Zm-.25-6.75Z', 'auto': 'M11 19q1.3 0 2.47-.52t2.03-1.5q-3.2-.2-5.35-2.49T8 9q0-.32.02-.64t.08-.61q-1.42.8-2.26 2.2T5 13q0 2.5 1.75 4.25T11 19Zm0 2q-3.35 0-5.67-2.32t-2.33-5.68q0-3.35 2.32-5.67t5.68-2.33q.13 0 .25.01t.25.01q-.72.8-1.11 1.83T10 9q0 2.5 1.75 4.25T16 15q.78 0 1.51-.19t1.4-.56q-.45 2.95-2.7 4.85T11 21Zm2.8-10 3.2-9h2l3.2 9h-1.9l-.7-2H17.4l-.7 2h-1.9Zm3.05-3.35h2.3l-1.15-3.65-1.15 3.65ZM10.18-9.53Z', 'palette': 'M12 22q-2.05 0-3.875-.788t-3.187-2.15Q3.575 17.7 2.788 15.875T2 12q0-2.075.812-3.9t2.2-3.175Q6.4 3.575 8.25 2.788T12.2 2q2 0 3.775.688t3.112 1.9q1.338 1.212 2.125 2.875T22 10.95q0 2.875-1.75 4.413T16 17h-1.85q-.225 0-.313.125t-.087.275q0 .3 0.375.863T14.5 20.3q0 1.25-.688 1.85T12 22Zm0-10Zm-4.425.575q.425-.425.425-1.075t-.425-1.075q-.425-.425-1.075-.425t-1.075.425q-.425.425-.425 1.075t.425 1.075q.425.425 1.075.425t1.075-.425Zm3-4q.425-.425.425-1.075t-.425-1.075q-.425-.425-1.075-.425t-1.075.425q-.425.425-.425 1.075t.425 1.075q.425.425 1.075.425t1.075-.425Zm5 0q.425-.425.425-1.075t-.425-1.075q-.425-.425-1.075-.425t-1.075.425q-.425.425-.425 1.075t.425 1.075q.425.425 1.075.425t1.075-.425Zm3 4q.425-.425.425-1.075t-.425-1.075q-.425-.425-1.075-.425t-1.075.425q-.425.425-.425 1.075t.425 1.075q.425.425 1.075.425t1.075-.425ZM12 20q.225 0 .363-.125t.137-.325q0-.35-.375-.825T11.75 17.3q0-1.05.725-1.675T14.25 15h1.75q1.65 0 2.825-.963T20 10.95q0-3.025-2.312-5.038T12.2 3.9q-3.4 0-5.8 2.325T4 11.95q0 3.325 2.338 5.663T12 20Z', 'dropdown': 'M7 10l5 5 5-5H7z', 'thermostat': 'M15 13V5A3 3 0 0 0 9 5V13A5 5 0 1 0 15 13M12 4A1 1 0 0 1 13 5V8H11V5A1 1 0 0 1 12 4Z' }; interface ListItem { label: string; description: string; icon: string; oid: string; disableIf?: string; category: 'system' | 'appearance'; } // === EURE LISTEN-EINTRÄGE === function getListItems(): ListItem[] { const isPrivacy = getSafeVal(DP_PRIVACY, false) === true; const nameUser1 = isPrivacy ? 'Bewohner 1' : 'Eigener Name'; return [ { category: 'system', label: 'Rollladen Automatik', description: 'Die Rollladen werden nach Sonnenuntergang automatisch geschlossen.', icon: 'sun', oid: 'javascript.0.routines.auto_blinds' }, { category: 'system', label: 'WakeUp-Automatik', description: 'Bei Bewegung nach 6 Uhr am Morgen werden die Rolladen geöffnet.', icon: 'alarm', oid: 'javascript.0.routines.wakeup' }, { category: 'system', label: 'Partymodus', description: 'Schlaf-Taste bleibt verborgen. Automatiken werden pausiert.', icon: 'party', oid: '0_userdata.0.System.Partymodus' }, { category: 'system', label: 'Gäste im Haus', description: 'Verhindert das automatische Ausschalten in bestimmten Bereichen.', icon: 'guests', oid: '0_userdata.0.System.Gaeste' }, { category: 'system', label: nameUser1, description: `Für ${nameUser1} wird eine individuelle Routine aktiviert.`, icon: 'person', oid: 'javascript.0.routines.user1_routine' }, { category: 'appearance', label: 'Privacy Mode (Demo)', description: 'Anonymisiert Namen und Bilder für Screenshots.', icon: 'person', oid: DP_PRIVACY }, { category: 'appearance', label: 'Google JSON Theme', description: 'Aktiv: Nutzt Custom-JSON. Inaktiv: Farben aus dem Wallpaper.', icon: 'palette', oid: `${BASE_PATH}.themeUseJson` }, { category: 'appearance', label: 'Auto-Theme (Astro)', description: 'Wechselt bei Sonnenuntergang in den Dark-Mode.', icon: 'auto', oid: `${BASE_PATH}.autoTheme` }, { category: 'appearance', label: 'Manueller Dark Mode',description: 'Überschreibt das Farbschema (Wenn Auto-Theme aus ist).', icon: 'moon', oid: `${BASE_PATH}.darkMode`, disableIf: `${BASE_PATH}.autoTheme` } ]; } interface WallpaperItem { label: string; path: string; } function getDynamicWallpapers(): WallpaperItem[] { let wallpapers: WallpaperItem[] = []; try { if (fs.existsSync(WALLPAPER_SYS_DIR)) { const files = fs.readdirSync(WALLPAPER_SYS_DIR); files.forEach((file: string) => { const ext = file.toLowerCase(); if (ext.endsWith('.jpg') || ext.endsWith('.jpeg') || ext.endsWith('.png') || ext.endsWith('.webp')) { let cleanName = file.replace(/\.[^/.]+$/, "").replace(/[_-]/g, ' ').replace(/\b\w/g, c => c.toUpperCase()); wallpapers.push({ label: cleanName, path: WALLPAPER_WEB_DIR + file }); } }); } } catch (e: any) { // Ordner existiert nicht oder fs Modul fehlt } wallpapers.sort((a, b) => a.label.localeCompare(b.label)); return wallpapers; } let DYNAMIC_WALLPAPERS: WallpaperItem[] = getDynamicWallpapers(); function svgIcon(name: string, color: string, size: number = 24): string { const path = ICONS[name] || ICONS['person']; return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" style="flex-shrink:0; transition: fill 0.3s ease;"><path fill="${color}" d="${path}"/></svg>`; } function getSafeVal(oid: string, fallback: any = false): any { if (existsState(oid)) return getState(oid).val; return fallback; } function getWallpaperNameByPath(path: string): string { const found = DYNAMIC_WALLPAPERS.find(wp => wp.path === path); return found ? found.label : 'Auswählen...'; } function renderListItem(item: ListItem): string { const rawVal = getSafeVal(item.oid, false); const active = (rawVal === true || rawVal === 1 || rawVal === 'true'); let disabled = false; if (item.disableIf) disabled = (getSafeVal(item.disableIf, false) === true); const trackBg = active ? M3.primary : M3.surfaceContainerHighest; const trackBorder = active ? M3.primary : M3.outline; const thumbSize = active ? 24 : 16; const thumbColor = active ? M3.onPrimary : M3.outline; const thumbLeft = active ? 'calc(100% - 26px)' : '6px'; const opacity = disabled ? '0.4' : '1'; const pointerEvents = disabled ? 'none' : 'auto'; const clickAction = disabled ? "" : `(function(e){ e.stopPropagation(); if(typeof vis!=='undefined'&&vis.conn&&vis.conn.setState)vis.conn.setState('${item.oid}', ${!active}); else if(typeof vis!=='undefined'&&vis.setValue)vis.setValue('${item.oid}', ${!active}); })(event);`.replace(/\n/g, ' '); const rippleJS = disabled ? "" : `(function(e,el){var evt=e.touches?e.touches[0]:e;if(!evt.clientX)return;var d=Math.max(el.clientWidth,el.clientHeight);var r=d/2;var rect=el.getBoundingClientRect();var x=evt.clientX-rect.left;var y=evt.clientY-rect.top;var c=document.createElement('span');c.style.width=c.style.height=d+'px';c.style.left=(x-r)+'px';c.style.top=(y-r)+'px';c.style.position='absolute';c.style.borderRadius='50%';c.style.backgroundColor='var(--m3-on-surface-variant)';c.style.opacity='0.1';c.style.transform='scale(0)';c.style.animation='m3-ripple-anim 0.5s linear';c.style.pointerEvents='none';el.appendChild(c);setTimeout(function(){c.remove();},500);})(event,this)`; return ` <div onclick="${clickAction}" onmousedown="${rippleJS}" ontouchstart="${rippleJS}" style="position:relative; overflow:hidden; width:100%; border-radius:16px; padding:12px 16px; box-sizing:border-box; background:${M3.surfaceContainerLow}; cursor:${disabled ? 'default' : 'pointer'}; user-select:none; display:flex; align-items:center; opacity:${opacity}; pointer-events:${pointerEvents}; font-family:Roboto,'Segoe UI',system-ui,sans-serif; margin-bottom: 8px; -webkit-tap-highlight-color:transparent; transition: background-color 0.3s ease;"> <div style="flex: 0 0 40px; width:40px; height:40px; border-radius:50%; background:${M3.surfaceVariant}; display:flex; align-items:center; justify-content:center; margin-right:14px;"> ${svgIcon(item.icon, M3.onSurfaceVariant, 20)} </div> <div style="flex: 1 1 0%; min-width: 0; display: block; padding: 2px 0;"> <div style="font-size:16px; font-weight:500; color:${M3.onSurface}; line-height:1.3; margin-bottom:2px; white-space:normal; overflow-wrap:break-word;">${item.label}</div> <div style="font-size:13px; font-weight:400; color:${M3.onSurfaceVariant}; opacity:0.85; line-height:1.4; white-space:normal; overflow-wrap:break-word;">${item.description}</div> </div> <div style="flex: 0 0 52px; width:52px; height:32px; margin-left:12px; border-radius:16px; background:${trackBg}; border:2px solid ${trackBorder}; box-sizing:border-box; position:relative; transition:all 0.25s cubic-bezier(0.2, 0, 0, 1);"> <div style="position:absolute; left:${thumbLeft}; top:50%; transform:translateY(-50%); width:${thumbSize}px; height:${thumbSize}px; border-radius:50%; background:${thumbColor}; transition:all 0.25s cubic-bezier(0.2, 0, 0, 1);"></div> </div> </div>`; } // === RECHTSBÜNDIGE FILTER CHIPS === function renderChartChips(): string { const actVal = getSafeVal(DP_CHART_ACT, true); const setVal = getSafeVal(DP_CHART_SET, true); const winVal = getSafeVal(DP_CHART_WINDOW, true); const brennerVal = getSafeVal(DP_CHART_BRENNER, true); const valveVal = getSafeVal(DP_CHART_VALVE, false); const humidVal = getSafeVal(DP_CHART_HUMID, true); const makeChip = (label: string, active: boolean, dp: string) => { const bg = active ? M3.primaryContainer : 'transparent'; const fg = active ? M3.onPrimaryContainer : M3.onSurfaceVariant; const border = active ? `1px solid ${M3.primaryContainer}` : `1px solid ${M3.outline}`; const iconHtml = active ? `<svg width="18" height="18" viewBox="0 0 24 24" style="margin-right:4px; margin-left:-4px;"><path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>` : ''; const js = `(function(e){ e.stopPropagation(); if(typeof vis!=='undefined'&&vis.conn&&vis.conn.setState)vis.conn.setState('${dp}', ${!active}); else if(typeof vis!=='undefined'&&vis.setValue)vis.setValue('${dp}', ${!active}); })(event);`.replace(/\n/g, ' '); return `<div onclick="${js}" style="display:inline-flex; align-items:center; height:32px; padding:0 12px; border-radius:8px; background:${bg}; border:${border}; color:${fg}; font-size:14px; font-weight:500; cursor:pointer; transition:all 0.2s ease;">${iconHtml}${label}</div>`; }; return ` <div style="width:100%; border-radius:16px; padding:12px 16px; box-sizing:border-box; background:${M3.surfaceContainerLow}; margin-bottom:8px; font-family:Roboto,'Segoe UI',system-ui,sans-serif; display:flex; align-items:flex-start;"> <div style="flex:0 0 40px; width:40px; height:40px; border-radius:50%; background:${M3.surfaceVariant}; display:flex; align-items:center; justify-content:center; margin-right:14px;"> ${svgIcon('thermostat', M3.onSurfaceVariant, 20)} </div> <div style="flex: 1 1 0%; min-width: 0;"> <div style="font-size:16px; font-weight:500; color:${M3.onSurface}; margin-bottom:2px;">Graphen-Anzeige</div> <div style="font-size:13px; color:${M3.onSurfaceVariant}; opacity:0.85; margin-bottom:12px; line-height:1.4;">Wähle aus, welche Linien in den Diagrammen gezeichnet werden.</div> <div style="display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end;"> ${makeChip('Ist-Temp', actVal, DP_CHART_ACT)} ${makeChip('Soll-Temp', setVal, DP_CHART_SET)} ${makeChip('Luftfeuchte', humidVal, DP_CHART_HUMID)} ${makeChip('Fenster', winVal, DP_CHART_WINDOW)} ${makeChip('Brenner', brennerVal, DP_CHART_BRENNER)} ${makeChip('Ventil', valveVal, DP_CHART_VALVE)} </div> </div> </div>`; } function renderMenuWallpaperItem(wp: WallpaperItem, currentPath: string): string { const active = (wp.path === currentPath); const bg = active ? M3.surfaceVariant : 'transparent'; const textColor = active ? M3.primary : M3.onSurface; const clickAction = `(function(e){ e.stopPropagation(); if(typeof vis!=='undefined'&&vis.conn&&vis.conn.setState)vis.conn.setState('${DP_IMAGE_PATH}', '${wp.path}'); else if(typeof vis!=='undefined'&&vis.setValue)vis.setValue('${DP_IMAGE_PATH}', '${wp.path}'); document.getElementById('m3-wallpaper-menu').style.opacity='0'; document.getElementById('m3-wallpaper-menu').style.pointerEvents='none'; })(event);`.replace(/\n/g, ' '); return `<div onclick="${clickAction}" style="position:relative; width:100%; padding:10px 16px; box-sizing:border-box; border-radius:12px; background:${bg}; cursor:pointer; user-select:none; margin-bottom:2px; display:flex; align-items:center; font-family:Roboto,'Segoe UI',system-ui,sans-serif; -webkit-tap-highlight-color:transparent; transition: background-color 0.2s ease;"> <img src="${wp.path}" style="flex:0 0 44px; width:44px; height:32px; border-radius:6px; object-fit:cover; background:${M3.surfaceVariant}; margin-right:14px;"> <div style="flex:1 1 0%; min-width:0; display:block; font-size:15px; font-weight:500; color:${textColor}; line-height:1.4; white-space:normal; overflow-wrap:break-word;">${wp.label}</div> </div>`; } function renderSetup(): void { const allItems = getListItems(); const systemHtml = allItems.filter(item => item.category === 'system').map(item => renderListItem(item)).join(''); const appearanceHtml = allItems.filter(item => item.category === 'appearance').map(item => renderListItem(item)).join(''); const chartChipsHtml = renderChartChips(); const currentWpPath = getSafeVal(DP_IMAGE_PATH, ''); const currentWpName = getWallpaperNameByPath(currentWpPath); const menuItemsHtml = DYNAMIC_WALLPAPERS.map(wp => renderMenuWallpaperItem(wp, currentWpPath)).join(''); const openMenuJS = `document.getElementById('m3-wallpaper-menu').style.opacity='1'; document.getElementById('m3-wallpaper-menu').style.pointerEvents='auto';`; const closeMenuJS = `document.getElementById('m3-wallpaper-menu').style.opacity='0'; document.getElementById('m3-wallpaper-menu').style.pointerEvents='none';`; const rippleJS = `(function(e,el){var evt=e.touches?e.touches[0]:e;if(!evt.clientX)return;var d=Math.max(el.clientWidth,el.clientHeight);var r=d/2;var rect=el.getBoundingClientRect();var x=evt.clientX-rect.left;var y=evt.clientY-rect.top;var c=document.createElement('span');c.style.width=c.style.height=d+'px';c.style.left=(x-r)+'px';c.style.top=(y-r)+'px';c.style.position='absolute';c.style.borderRadius='50%';c.style.backgroundColor='var(--m3-on-surface-variant)';c.style.opacity='0.1';c.style.transform='scale(0)';c.style.animation='m3-ripple-anim 0.5s linear';c.style.pointerEvents='none';el.appendChild(c);setTimeout(function(){c.remove();},500);})(event,this)`; const html = ` <style> @keyframes m3-ripple-anim { to { transform: scale(4); opacity: 0; } } [id^="vis_widget_"] .vis-view-inner-html-html, [id^="vis_widget_"] .vis-view-inner-html-html > div { height: 100% !important; } .m3-scroll-container::-webkit-scrollbar, .m3-menu-scroll::-webkit-scrollbar { width: 6px; } .m3-scroll-container::-webkit-scrollbar-track, .m3-menu-scroll::-webkit-scrollbar-track { background: transparent; } .m3-scroll-container::-webkit-scrollbar-thumb, .m3-menu-scroll::-webkit-scrollbar-thumb { background: var(--m3-outline-variant); border-radius: 3px; } .m3-scroll-container::-webkit-scrollbar-thumb:hover, .m3-menu-scroll::-webkit-scrollbar-thumb:hover { background: var(--m3-outline); } </style> <div class="m3-scroll-container" style="position: absolute; inset: 0; background: var(--m3-surface-container-low, rgb(237, 239, 232)); border-radius: 0 0 28px 28px; padding: 24px; display: block; width: 100%; box-sizing: border-box; overflow-y: auto; transition: background-color 0.3s ease;"> <div style="font-size:12px; font-weight:700; color:${M3.primary}; text-transform:uppercase; letter-spacing:1.2px; margin: 4px 0 8px 4px;">Erscheinungsbild & Anzeige</div> ${appearanceHtml} ${chartChipsHtml} <div style="position:relative; width:100%; border-radius:16px; padding:12px 16px; box-sizing:border-box; background:${M3.surfaceContainerLow}; user-select:none; margin-bottom:24px; display:flex; align-items:center; font-family:Roboto,'Segoe UI',system-ui,sans-serif; -webkit-tap-highlight-color:transparent; transition: all 0.3s ease;"> <div style="flex:0 0 40px; width:40px; height:40px; border-radius:50%; background:${M3.surfaceVariant}; display:flex; align-items:center; justify-content:center; margin-right:14px;">${svgIcon('palette', M3.onSurfaceVariant, 20)}</div> <div style="flex:1 1 0%; min-width:0; display:block;"><div style="font-size:16px; font-weight:500; color:${M3.onSurface}; line-height:normal;">Hintergrundbild</div></div> <div onclick="${openMenuJS}" onmousedown="${rippleJS}" ontouchstart="${rippleJS}" style="flex:0 0 auto; margin-left:12px; position:relative; overflow:hidden; display:flex; align-items:center; gap:8px; background:${M3.surfaceVariant}; padding:8px 16px; border-radius:20px; cursor:pointer; color:${M3.onSurfaceVariant}; transition: background-color 0.2s ease;"> <span style="font-size:14px; font-weight:500; line-height:normal;">${currentWpName}</span>${svgIcon('dropdown', M3.onSurfaceVariant, 20)} </div> </div> <div style="font-size:12px; font-weight:700; color:${M3.primary}; text-transform:uppercase; letter-spacing:1.2px; margin: 0 0 8px 4px;">System & Automatiken</div> ${systemHtml} <div style="height: 24px; flex-shrink: 0;"></div> </div> <div id="m3-wallpaper-menu" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 999999; display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity 0.2s;"> <div onclick="${closeMenuJS}" style="position: absolute; inset: 0; background: rgba(0,0,0,0.4);"></div> <div style="position: relative; width: 380px; max-height: 80vh; background: var(--m3-surface-container-highest, #e1e3dc); border-radius: 20px; box-shadow: 0 12px 32px rgba(0,0,0,0.3); display: flex; flex-direction: column; overflow: hidden; font-family:Roboto,'Segoe UI',system-ui,sans-serif;"> <div style="padding: 20px 24px 12px 24px; font-size: 15px; font-weight: 600; color:${M3.onSurfaceVariant}; border-bottom: 1px solid ${M3.outlineVariant};">Hintergrundbild auswählen</div> <div class="m3-menu-scroll" style="overflow-y: auto; padding: 12px; display:flex; flex-direction:column;"> ${DYNAMIC_WALLPAPERS.length > 0 ? menuItemsHtml : `<div style="padding:20px; text-align:center; color:${M3.onSurfaceVariant}; font-size:14px;">Keine Bilder gefunden. Ordner prüfen!</div>`} </div> </div> </div>`; setState(DP_SETUP_HTML, html, true); } // === INIT & SUBSCRIPTIONS ====================================================== // Verschachtelte createState Aufrufe stellen sicher, dass alle Datenpunkte existieren, bevor abonniert wird. createState(DP_SETUP_HTML, '', { type: 'string', name: 'Setup HTML (M3)', role: 'html' }, () => { createState(DP_CHART_BRENNER, true, { type: 'boolean', name: 'Show Brenner Chart', role: 'switch' }, () => { createState(DP_CHART_VALVE, false, { type: 'boolean', name: 'Show Valve Chart', role: 'switch' }, () => { createState(DP_CHART_ACT, true, { type: 'boolean', name: 'Show Actual Temp Chart', role: 'switch' }, () => { createState(DP_CHART_SET, true, { type: 'boolean', name: 'Show Set Temp Chart', role: 'switch' }, () => { createState(DP_CHART_WINDOW, true, { type: 'boolean', name: 'Show Window Chart', role: 'switch' }, () => { createState(DP_CHART_HUMID, true, { type: 'boolean', name: 'Show Humidity Chart', role: 'switch' }, () => { createState(DP_PRIVACY, false, { type: 'boolean', name: 'Privacy Mode Toggle', role: 'switch' }, () => { createState(DP_IMAGE_PATH, '', { type: 'string', name: 'Theme Image Path', role: 'text' }, () => { getListItems().forEach(item => { if (existsState(item.oid)) on({ id: item.oid, change: 'any' }, () => renderSetup()); if (item.disableIf && existsState(item.disableIf)) on({ id: item.disableIf, change: 'any' }, () => renderSetup()); }); on({ id: [DP_CHART_BRENNER, DP_CHART_VALVE, DP_CHART_ACT, DP_CHART_SET, DP_CHART_WINDOW, DP_CHART_HUMID], change: 'any' }, () => renderSetup()); on({ id: DP_IMAGE_PATH, change: 'any' }, () => renderSetup()); renderSetup(); }); }); });});});});});}); }); [image: 1773605233417-setup2.jpg] [image: 1773605233425-setup1.jpg]
  • Zeigt her eure Visu

    vis
    127
    2 Stimmen
    127 Beiträge
    30k Aufrufe
    M
    @Horst-Böttcher Ich habe begonnen die Skripte hier zu veröffentlichen.
  • In VIS nach verwaisten Datenpunkten suchen?

    13
    0 Stimmen
    13 Beiträge
    317 Aufrufe
    M
    Der Ansatz ist gut, nun schränkt sich die Suche schon mal ein. Man kann dann die Länsten schon noch manuell suchen. Danke für die Antwort.
  • VIS2 Metro Tile ValueList

    10
    2
    0 Stimmen
    10 Beiträge
    869 Aufrufe
    skvarelS
    @Qlink .. hast du dir mal unsere inventwo Widgets angeschaut? Da kannst du beliebig viele Zustände hinzufügen. [image: 1773480918030-cbecce53-5c6e-4931-943a-427f499429f3-image.png]
  • VIS2 - CSS allgemein - Nur für Gruppen

    vis
    2
    0 Stimmen
    2 Beiträge
    113 Aufrufe
    I
    Ich muss nochmal nachfragen, da bislang niemand geantwortet hat. Bin ich der Einzige mit dem Problem oder nutzt niemand die Funktion ganze Seiten abhängig vom Benutzer/Gruppe ausblenden zu lassen, so dass sie auch im Navigationsmenü nicht erscheinen? Oder nutzt ihr eine mir bisher verborgene Technik, um das zu realisieren. Danke
  • [gelöst] VIS-2: Problem mit dem"Gauge" (Widget-Sammlung)

    20
    1
    0 Stimmen
    20 Beiträge
    365 Aufrufe
    fuzzy1955F
    @carsten04 sagte in [gelöst] VIS-2: Problem mit dem"Gauge" (Widget-Sammlung): Du warst noch auf einer ziemlich alten Version Ja, klar. Diese war im Stable. Danke für deine Tipps!
  • [gelöst] VIS-1 - externes Widget einbinden

    7
    1
    0 Stimmen
    7 Beiträge
    107 Aufrufe
    OliverIOO
    @bommel_030 sagte in [gelöst] VIS-1 - externes Widget einbinden: Das umformatieren hätte ich aber nicht hinbekommen. Ich mach das mit notepad++ und Plugin jstools Zum formatieren
  • Problem mit "Vis 2 inventwo Widgets" Update > v0.2.2

    20
    2
    0 Stimmen
    20 Beiträge
    1k Aufrufe
    T
    Also, dieses Vorgehen kann ich bei meiner Installation nicht bestätigen! Ich habe HTTPS immer aktiv. Übrigens: Update auf 0.6.1 lief bei mir problemlos!
  • [erledigt] VIS-2 Visualisierung funktioniert nicht mehr

    35
    3
    0 Stimmen
    35 Beiträge
    700 Aufrufe
    fuzzy1955F
    @OliverIO sagte in [erledigt] VIS-2 Visualisierung funktioniert nicht mehr: Der Import von vis1 funktioniert fast nie, falls du gerade erst umsteigst Wie oben mehrfach gepostet, habe ich VIS-1 NIE verwendet. Das ist jetzt der Browser-Konsolen-Inhalt des neu aufgesetzten IOBrokers inkl. der neu erstellten VIS-2-Seite "home": iobroker.vis-2@2.13.3 index-BsOYribJ.js:7770 ██╗ ██████╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗███████╗██████╗ ██║██╔═══██╗██╔══██╗██╔══██╗██╔═══██╗██║ ██╔╝██╔════╝██╔══██╗ ██║██║ ██║██████╔╝██████╔╝██║ ██║█████╔╝ █████╗ ██████╔╝ ██║██║ ██║██╔══██╗██╔══██╗██║ ██║██╔═██╗ ██╔══╝ ██╔══██╗ ██║╚██████╔╝██████╔╝██║ ██║╚██████╔╝██║ ██╗███████╗██║ ██║ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ index-BsOYribJ.js:7777 Nice to see you here! :) Join our dev community here https://github.com/ioBroker/ioBroker or here https://github.com/iobroker-community-adapters index-BsOYribJ.js:7777 Help us to create open source project with reactJS! index-BsOYribJ.js:7777 See you :) blob:http://192.168.0.100:8082/8d6a0a45-112a-4afc-8bba-cef3ad931f43:1 Manifest: property 'start_url' ignored, URL is invalid. blob:http://192.168.0.100:8082/8d6a0a45-112a-4afc-8bba-cef3ad931f43:1 Manifest: property 'src' ignored, URL is invalid. index-BelaSnNa.js:7246 Skip script "jqplot" widgets/jqplot/js/jquery.jqplot.min.js 2index-BelaSnNa.js:7246 Skip script "jqplot" inline index-BelaSnNa.js:7246 Skip script "jqui" lib/js/jquery-ui-timepicker-addon-1.6.3.js index-BelaSnNa.js:7246 Skip script "jqui" inline 3index-BelaSnNa.js:7246 Skip script "swipe" inline index-BelaSnNa.js:7246 Skip script "tabs" inline index-BsOYribJ.js:8208 Translate: jqui_widgetTitle index-BsOYribJ.js:8208 Translate: jqui_Write state index-BsOYribJ.js:8208 Translate: jqui_Close index-BsOYribJ.js:8208 Translate: jqui_input index-BsOYribJ.js:8208 Translate: jqui_off index-BsOYribJ.js:8208 Translate: jqui_on index-BsOYribJ.js:8208 Translate: Value visView-CDuz12o6.js:22279 Ignored jqplot/tplJqplotGauge because not used in project visView-CDuz12o6.js:22279 Ignored swipe/tplCarousel because not used in project index-BelaSnNa.js:7400 [2026-03-07T19:31:30.419Z] +SUBSCRIBE: alias.0.Hausstrom.Hausakku.BatterieLadezustand index-BelaSnNa.js:7400 [2026-03-07T19:31:30.426Z] +SUBSCRIBE: alias.0.Hausstrom.Allgemein.PrioritaetsText index-BelaSnNa.js:7400 [2026-03-07T19:31:30.429Z] +SUBSCRIBE: alias.0.Hausstrom.Allgemein.StromleistungHaus index-BelaSnNa.js:7400 [2026-03-07T19:31:30.431Z] +SUBSCRIBE: alias.0.Hausstrom.Allgemein.StromLeistungNot index-BelaSnNa.js:7400 [2026-03-07T19:31:30.433Z] +SUBSCRIBE: alias.0.Diagrammdaten.StromPV index-BelaSnNa.js:7400 [2026-03-07T19:31:30.435Z] +SUBSCRIBE: alias.0.Hausstrom.PvModule.PvErzeugung index-BelaSnNa.js:7400 [2026-03-07T19:31:30.437Z] +SUBSCRIBE: alias.0.Klimatisierung.Boiler.Boilertemperatur index-BelaSnNa.js:7400 [2026-03-07T19:31:30.438Z] +SUBSCRIBE: alias.0.Hausstrom.Allgemein.StromleistungGenerator index-BelaSnNa.js:7400 [2026-03-07T19:31:30.440Z] +SUBSCRIBE: alias.0.Hausstrom.Wallbox.Allgemein.LeistungIst index-BelaSnNa.js:7400 [2026-03-07T19:31:30.442Z] +SUBSCRIBE: alias.0.Hausstrom.Wallbox.Allgemein.Kabelstatustext index-BelaSnNa.js:7400 [2026-03-07T19:31:30.443Z] +SUBSCRIBE: alias.0.Hausstrom.Wechselrichter.GenNetzsignalText index-BelaSnNa.js:7400 [2026-03-07T19:31:30.444Z] +SUBSCRIBE: alias.0.Hausstrom.Wechselrichter.WrTemperaturM01 index-BelaSnNa.js:7400 [2026-03-07T19:31:30.445Z] +SUBSCRIBE: alias.0.Hausstrom.Wechselrichter.WrTemperaturS02 index-BelaSnNa.js:7400 [2026-03-07T19:31:30.447Z] +SUBSCRIBE: alias.0.Hausstrom.Wechselrichter.WrGesamtleistungAC index-BelaSnNa.js:7400 [2026-03-07T19:31:30.448Z] +SUBSCRIBE: alias.0.Hausstrom.Wechselrichter.WrGesamtleistungDC index-BelaSnNa.js:7400 [2026-03-07T19:31:30.452Z] +SUBSCRIBE: alias.0.Klimatisierung.Boiler.Boilerregler index-BelaSnNa.js:7400 [2026-03-07T19:31:30.453Z] +SUBSCRIBE: alias.0.Klimatisierung.Boiler.Boilerleistung index-BelaSnNa.js:7400 [2026-03-07T19:31:30.454Z] +SUBSCRIBE: alias.0.Hausstrom.Allgemein.StromverlustleistungWR index-BelaSnNa.js:7400 [2026-03-07T19:31:30.455Z] +SUBSCRIBE: alias.0.Hausstrom.Hausakku.BatterieLeistung index.js:13 iobroker.echarts-show@1.9.2" console.ts:40 Read till Sat Mar 07 2026 20:31:31 GMT+0100 (Mitteleuropäische Normalzeit) [NEW] Explain Console errors by using Copilot in Edge: click to explain an error. Learn more Und wenn du nochmal ein log postest Pardon. Ich dachte der Spoiler bringt das Gleiche.
  • ViS2 zeigt neuerdings tooltip in Navigation

    1
    1
    0 Stimmen
    1 Beiträge
    93 Aufrufe
    Niemand hat geantwortet
  • VIS-2 Inventwo Sortierung für jsonTable fehlt

    5
    0 Stimmen
    5 Beiträge
    125 Aufrufe
    skvarelS
    @MCU .. da werden wir nichts machen können. Ich hatte das schon mit meinem Sohn besprochen. Es ist halt ein String (Text) und der wird leider so sortiert. Die 1xxx kommt vor der 2x dann kommt die 3x
  • Energiefluss-Adapter - Transparenter Hintergrund via CSS

    5
    1
    0 Stimmen
    5 Beiträge
    143 Aufrufe
    L
    Genauuuuuuuuuu sooooooooo! Vielen lieben Dank! Man ist einfach betriebsblind geworden und da ist es super wenn es Leute wie Dich gibt! Danke - das wars ... LG Lars
  • Systemfarbe Vis 2 App anpassen

    50
    0 Stimmen
    50 Beiträge
    861 Aufrufe
    B
    Egal, danke für deine Unterstützung. Bis demnächst ...
  • [gelöst] VIS2-Inventwo Darstellung für Trashschedule

    9
    1
    0 Stimmen
    9 Beiträge
    198 Aufrufe
    skvarelS
    [image: 1772632198640-5c2ef3dd-fdd3-42bf-9057-5c2ff52b98e3-image.png]
  • VIS 2: WLED Effekt (seg.0.fx) als Dropdown anzeigen

    50
    0 Stimmen
    50 Beiträge
    1k Aufrufe
    R
    @skvarel ui sorry, dass war ein widget von der vis2-widget Sammlung, mit dem vis-inventwo color picker läuft es nun, trotzdem danke

289

Online

32.8k

Benutzer

82.9k

Themen

1.3m

Beiträge