Weiter zum Inhalt
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Hell
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dunkel
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Visualisierung
  4. Zeigt her eure Bambu Lab Vis

NEWS

  • Neues YouTube-Video: Visualisierung im Devices-Adapter
    BluefoxB
    Bluefox
    11
    1
    529

  • Neuer ioBroker-Blog online: Monatsrückblick März/April 2026
    BluefoxB
    Bluefox
    8
    1
    1.9k

  • Verwendung von KI bitte immer deutlich kennzeichnen
    HomoranH
    Homoran
    11
    1
    855

Zeigt her eure Bambu Lab Vis

Geplant Angeheftet Gesperrt Verschoben Visualisierung
29 Beiträge 12 Kommentatoren 5.9k Aufrufe 13 Beobachtet
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • skvarelS skvarel

    ... update :)

    Meine neue VIS für ein ausrangiertes Tablet im Büro:
    80d1cbbf-ffb4-45a4-89d4-c8d12cb60b14-image.png

    Die Haupt-VIS:
    272cc84c-d780-4a0d-aa80-3c3bb9d41e6c-image.png

    Die Handy-VIS:
    d36e8556-696e-4a57-a6b6-7b7ccf111ddd-image.png

    E Offline
    E Offline
    Eggi
    schrieb am zuletzt editiert von
    #21

    @skvarel
    Hallo
    Deine VIS vom P1S gefällt mir sehr gut.
    Darf ich diese Verwenden? Wenn ja, bitte um Deine View (und alles was dazugehört)
    Vielen Dank im Voraus

    W 1 Antwort Letzte Antwort
    1
    • E Eggi

      @skvarel
      Hallo
      Deine VIS vom P1S gefällt mir sehr gut.
      Darf ich diese Verwenden? Wenn ja, bitte um Deine View (und alles was dazugehört)
      Vielen Dank im Voraus

      W Offline
      W Offline
      wolfgangkt
      schrieb am zuletzt editiert von
      #22

      Das wäre meine.

      Screenshot 2025-07-16 142824.png

      E 1 Antwort Letzte Antwort
      0
      • W wolfgangkt

        Das wäre meine.

        Screenshot 2025-07-16 142824.png

        E Offline
        E Offline
        Eggi
        schrieb am zuletzt editiert von
        #23

        @wolfgangkt
        Hallo Wolgang
        Darf ich bitte Deine VIS verwebden?!
        Danke im Voraus.

        W 1 Antwort Letzte Antwort
        0
        • E Eggi

          @wolfgangkt
          Hallo Wolgang
          Darf ich bitte Deine VIS verwebden?!
          Danke im Voraus.

          W Offline
          W Offline
          wolfgangkt
          schrieb am zuletzt editiert von
          #24

          @eggi
          kann die Vis-Seite gerne zu Verfügung stellen.
          Sind aber auch sehr viele Blockly-Skripte dahinter.

          E 1 Antwort Letzte Antwort
          0
          • W wolfgangkt

            @eggi
            kann die Vis-Seite gerne zu Verfügung stellen.
            Sind aber auch sehr viele Blockly-Skripte dahinter.

            E Offline
            E Offline
            Eggi
            schrieb am zuletzt editiert von
            #25

            @wolfgangkt
            ...Blockly-Scripte sind kein Problem - ich pick mir raus, was ich für meine Zwecke brauche (um das Rad nicht neu erfinden zu müssen)
            Danke im Voraus

            W 1 Antwort Letzte Antwort
            0
            • E Eggi

              @wolfgangkt
              ...Blockly-Scripte sind kein Problem - ich pick mir raus, was ich für meine Zwecke brauche (um das Rad nicht neu erfinden zu müssen)
              Danke im Voraus

              W Offline
              W Offline
              wolfgangkt
              schrieb am zuletzt editiert von
              #26

              @eggi
              ok, dann hier Bambu.zip

              1 Antwort Letzte Antwort
              0
              • H Online
                H Online
                helfi9999
                schrieb am zuletzt editiert von helfi9999
                #27

                Hallo zusammen, habe hier meine Bambulab VIS:
                ![Bild Text](da64e99c-da8e-4852-b59e-8128ec19c8e0-image.jpeg Bild Link)

                Habe dieses Skript


                /***********************

                • BambuLab AMS 0 + TEMP + PRINT + MEROSS
                • Komplett-Skript ohne AMS 1
                • Enthält:
                  • AMS 0 Tray 0 bis 3
                  • Farben + Schriftfarben
                  • Werte: Materialtyp;Filament-Untertyp
                  • aktiver Tray
                  • Temperatur
                  • Druckstatus
                  • Meross Adaptersteuerung
                    ***********************/

                const printerId = '01S00C321500283';

                const baseBambu = bambulab.0.${printerId};
                const baseAMS = '0_userdata.0.Bambulab.AMS';
                const baseTemp = '0_userdata.0.Bambulab.Temp';
                const basePrint = '0_userdata.0.Bambulab.Print';

                const merossId = 'meross.0.2303167546755151200348e1e9beebff.0';
                const adapterId = 'system.adapter.bambulab.0';

                const trayNowId = ${baseBambu}.ams.tray_now;

                const trayCount = 4;
                const defaultColor = '#D3D3D3';
                const refreshMs = 10000;

                const tempSources = {
                bedActual: ${baseBambu}.bed_temper,
                bedTarget: ${baseBambu}.bed_target_temper,
                nozzleActual: ${baseBambu}.nozzle_temper,
                nozzleTarget: ${baseBambu}.nozzle_target_temper
                };

                const printSources = {
                percent: ${baseBambu}.mc_percent,
                file: ${baseBambu}.gcode_file,
                state: ${baseBambu}.gcode_state,
                remaining: ${baseBambu}.mc_remaining_time
                };

                // ------------------------------------------------------------
                // Hilfsfunktionen
                // ------------------------------------------------------------

                function create(id, def, type = null, role = 'state') {
                if (!existsState(id)) {
                createState(id, {
                name: id.split('.').pop(),
                type: type || typeof def,
                role,
                read: true,
                write: true,
                def
                }, () => setState(id, def, true));
                }
                }

                function get(id) {
                const state = getState(id);
                return state ? state.val : undefined;
                }

                function set(id, val) {
                const state = getState(id);

                if (!state || state.val !== val) {
                    setState(id, val, true);
                }
                

                }

                function normalizeColor(raw) {
                let c = String(raw ?? '').replace('#', '').trim();
                c = c.replace(/[^0-9A-Fa-f]/g, '');

                if (c.length >= 6) {
                    return `#${c.substring(0, 6)}`.toUpperCase();
                }
                
                return defaultColor;
                

                }

                function getTextColor(color) {
                return String(color).toLowerCase() === '#000000' ? '#FFFFFF' : '#000000';
                }

                function formatTemp(v) {
                const n = Number(v);
                return isNaN(n) ? '-- °C' : ${Math.floor(n)} °C;
                }

                function parseRemaining(value) {
                if (value === null || value === undefined || value === '') return 0;

                const s = String(value).trim();
                
                const hm = s.match(/^(\d+):(\d+)$/);
                if (hm) return Number(hm[1]) * 60 + Number(hm[2]);
                
                if (!isNaN(Number(s))) return Number(s);
                
                return 0;
                

                }

                function formatRemaining(value) {
                const minutes = parseRemaining(value);
                if (minutes <= 0) return '--';

                const h = Math.floor(minutes / 60);
                const m = Math.floor(minutes % 60);
                
                return h > 0 ? `${h}h ${m}m` : `${m} min`;
                

                }

                function finishTime(value) {
                const minutes = parseRemaining(value);
                if (minutes <= 0) return '--';

                const end = new Date(Date.now() + minutes * 60000);
                
                return end.toLocaleTimeString('de-DE', {
                    hour: '2-digit',
                    minute: '2-digit'
                });
                

                }

                // ------------------------------------------------------------
                // Datenpunkte erstellen
                // ------------------------------------------------------------

                function createStates() {

                // AMS allgemein
                create(`${baseAMS}.Aktiver_Tray`, 255, 'number', 'value');
                create(`${baseAMS}.Farbe_aktiv`, defaultColor, 'string', 'value.color');
                create(`${baseAMS}.AMS_Farbe_aktiv`, defaultColor, 'string', 'value.color');
                
                // Aktive Tray-Boolean-Datenpunkte nur AMS 0
                create(`${baseAMS}.AMS0_Tray0`, false, 'boolean', 'indicator');
                create(`${baseAMS}.AMS0_Tray1`, false, 'boolean', 'indicator');
                create(`${baseAMS}.AMS0_Tray2`, false, 'boolean', 'indicator');
                create(`${baseAMS}.AMS0_Tray3`, false, 'boolean', 'indicator');
                
                // AMS 0 Tray 0 bis 3
                for (let tray = 0; tray < trayCount; tray++) {
                
                    // Struktur mit .0.
                    create(`${baseAMS}.0.Farbe_Tray_${tray}`, defaultColor, 'string', 'value.color');
                    create(`${baseAMS}.0.Schriftfarbe_Tray_${tray}`, '#000000', 'string', 'value.color');
                    create(`${baseAMS}.0.Werte_Tray_${tray}`, '', 'string', 'text');
                
                    // Einfache Struktur
                    create(`${baseAMS}.Farbe_Tray_${tray}`, defaultColor, 'string', 'value.color');
                    create(`${baseAMS}.Schriftfarbe_Tray_${tray}`, '#000000', 'string', 'value.color');
                    create(`${baseAMS}.Werte_Tray_${tray}`, '', 'string', 'text');
                }
                
                // Temperaturen
                create(`${baseTemp}.Ist_Druckbett`, '-- °C', 'string', 'text');
                create(`${baseTemp}.Soll_Druckbett`, '-- °C', 'string', 'text');
                create(`${baseTemp}.Ist_Duese`, '-- °C', 'string', 'text');
                create(`${baseTemp}.Soll_Duese`, '-- °C', 'string', 'text');
                
                // Print
                create(`${basePrint}.Fortschritt`, 0, 'number', 'value');
                create(`${basePrint}.Datei`, '', 'string', 'text');
                create(`${basePrint}.Status`, 'BEREIT', 'string', 'text');
                create(`${basePrint}.Restzeit`, '--', 'string', 'text');
                create(`${basePrint}.Fertig_um`, '--', 'string', 'text');
                

                }

                // ------------------------------------------------------------
                // AMS Farben + Schriftfarben + Werte
                // ------------------------------------------------------------

                function updateAMS() {

                for (let tray = 0; tray < trayCount; tray++) {
                    updateAmsTrayColor(tray);
                    updateAmsTrayWerte(tray);
                }
                
                updateActiveAmsTray();
                

                }

                function updateAmsTrayColor(tray) {

                const sourceColorId = `${baseBambu}.ams.ams.0.tray.${tray}.tray_color`;
                
                const color = normalizeColor(get(sourceColorId));
                const textColor = getTextColor(color);
                
                // Struktur mit .0.
                set(`${baseAMS}.0.Farbe_Tray_${tray}`, color);
                set(`${baseAMS}.0.Schriftfarbe_Tray_${tray}`, textColor);
                
                // Einfache Struktur
                set(`${baseAMS}.Farbe_Tray_${tray}`, color);
                set(`${baseAMS}.Schriftfarbe_Tray_${tray}`, textColor);
                

                }

                function updateAmsTrayWerte(tray) {

                const trayType = get(`${baseBambu}.ams.ams.0.tray.${tray}.tray_type`) ?? '';
                const subBrands = get(`${baseBambu}.ams.ams.0.tray.${tray}.tray_sub_brands`) ?? '';
                
                // Nur Materialtyp und Filament-Untertyp
                const wert = `${trayType};${subBrands}`;
                
                // Struktur mit .0.
                set(`${baseAMS}.0.Werte_Tray_${tray}`, wert);
                
                // Einfache Struktur
                set(`${baseAMS}.Werte_Tray_${tray}`, wert);
                

                }

                // ------------------------------------------------------------
                // Aktives AMS / aktiver Tray
                // ------------------------------------------------------------

                function updateActiveAmsTray() {

                const trayNow = Number(get(trayNowId));
                
                const trayStateNames = [
                    'AMS0_Tray0',
                    'AMS0_Tray1',
                    'AMS0_Tray2',
                    'AMS0_Tray3'
                ];
                
                // Erst alle Trays auf false setzen
                for (const name of trayStateNames) {
                    set(`${baseAMS}.${name}`, false);
                }
                
                // Kein aktiver Tray oder ungültiger Wert
                if (isNaN(trayNow) || trayNow === 255 || trayNow < 0 || trayNow > 3) {
                    set(`${baseAMS}.Aktiver_Tray`, 255);
                    set(`${baseAMS}.Farbe_aktiv`, defaultColor);
                    set(`${baseAMS}.AMS_Farbe_aktiv`, defaultColor);
                    return;
                }
                
                // Aktiven Tray setzen
                set(`${baseAMS}.Aktiver_Tray`, trayNow);
                set(`${baseAMS}.${trayStateNames[trayNow]}`, true);
                
                const activeColor = get(`${baseAMS}.0.Farbe_Tray_${trayNow}`) || defaultColor;
                
                set(`${baseAMS}.Farbe_aktiv`, activeColor);
                set(`${baseAMS}.AMS_Farbe_aktiv`, activeColor);
                

                }

                // ------------------------------------------------------------
                // Temperaturen
                // ------------------------------------------------------------

                function updateTemp() {
                set(${baseTemp}.Ist_Druckbett, formatTemp(get(tempSources.bedActual)));
                set(${baseTemp}.Soll_Druckbett, formatTemp(get(tempSources.bedTarget)));
                set(${baseTemp}.Ist_Duese, formatTemp(get(tempSources.nozzleActual)));
                set(${baseTemp}.Soll_Duese, formatTemp(get(tempSources.nozzleTarget)));
                }

                // ------------------------------------------------------------
                // Druckstatus
                // ------------------------------------------------------------

                function updatePrint() {
                const percent = Number(get(printSources.percent)) || 0;
                const file = String(get(printSources.file) ?? '');
                const rawState = String(get(printSources.state) ?? '').toUpperCase();
                const remainingRaw = get(printSources.remaining);
                const remaining = parseRemaining(remainingRaw);

                let status = rawState || 'BEREIT';
                
                if (remaining > 0 && percent > 0 && percent < 100) {
                    status = 'DRUCKT';
                } else if (percent >= 100) {
                    status = 'FERTIG';
                } else if (
                    rawState.includes('FAIL') ||
                    rawState.includes('CANCEL') ||
                    rawState.includes('ABORT')
                ) {
                    status = 'ABGEBROCHEN';
                } else if (remaining <= 0 && percent <= 0) {
                    status = 'BEREIT';
                }
                
                set(`${basePrint}.Status`, status);
                
                if (status === 'DRUCKT') {
                    set(`${basePrint}.Fortschritt`, percent);
                    set(`${basePrint}.Datei`, file);
                    set(`${basePrint}.Restzeit`, formatRemaining(remainingRaw));
                    set(`${basePrint}.Fertig_um`, finishTime(remainingRaw));
                } else {
                    set(`${basePrint}.Fortschritt`, 0);
                    set(`${basePrint}.Datei`, '');
                    set(`${basePrint}.Restzeit`, '--');
                    set(`${basePrint}.Fertig_um`, '--');
                }
                

                }

                // ------------------------------------------------------------
                // Alles aktualisieren
                // ------------------------------------------------------------

                function updateAll() {
                updateAMS();
                updateTemp();
                updatePrint();
                }

                // ------------------------------------------------------------
                // Trigger
                // ------------------------------------------------------------

                // Meross Steckdose / BambuLab Adapter
                on({ id: merossId, change: 'any' }, obj => {
                const isOn = obj.state.val === true || obj.state.val === 1 || obj.state.val === 'true';

                setState(`${adapterId}.alive`, isOn);
                
                if (isOn) {
                    setTimeout(updateAll, 8000);
                }
                

                });

                // AMS Änderungen nur AMS 0
                on({
                id: [
                trayNowId,
                new RegExp(^bambulab\\.0\\.${printerId}\\.ams\\.ams\\.0\\.tray\\.[0-3]\\.),
                ${baseBambu}.sequence_id
                ],
                change: 'any'
                }, updateAMS);

                // Temperatur Änderungen
                on({
                id: Object.values(tempSources),
                change: 'any'
                }, updateTemp);

                // Druckstatus Änderungen
                on({
                id: Object.values(printSources),
                change: 'any'
                }, updatePrint);

                // ------------------------------------------------------------
                // Start
                // ------------------------------------------------------------

                createStates();

                setTimeout(updateAll, 3000);
                setInterval(updateAll, refreshMs);


                Der Drucker wird über Steckdose von Meross gestartet zugleich wird der bambulab.adapter mit gestartet (da der Adapter sonst Meldungen macht wenn der Drucker ausgeschaltet ist im Log). Das Skript liest die Farben aus etc.

                Intel NUC mit Iobroker

                1 Antwort Letzte Antwort
                0
                • M mdumbsky

                  @darkmann2000

                  Hier die Dateien für meinen BambuLab P1P-View:
                  P1P_view.txt

                  Hier die verwendeten Blockly-Scripte:
                  Blockly_Farben_AMS_aktualisieren.txt
                  Blockly_Anzeige_Werte_AMS.txt
                  Blockly_Anzeige_Farben_Pfade_AMS.txt

                  Hier die von mir angelegten und verwendeten Datenpunkte:
                  Bild_2023-10-16_234652239.png

                  Hier das verwendete Bild für den Druckkopf:
                  Druckkopf_Zeichnung_Neu_P1P.png

                  Viel Spaß damit.

                  Gruß
                  Michael

                  H Online
                  H Online
                  helfi9999
                  schrieb am zuletzt editiert von helfi9999
                  #28

                  @mdumbsky Hi habe ein wenig deine Blckly Skripte geändert in Java Skript vielleicht ist das was für dich:

                  /***********************
                  * BambuLab AMS 0 + TEMP + PRINT + MEROSS
                  * Komplett-Skript ohne AMS 1
                  *
                  * Enthält:
                  * - AMS 0 Tray 0 bis 3
                  * - Farben + Schriftfarben
                  * - Werte: Materialtyp;Filament-Untertyp
                  * - aktiver Tray
                  * - Temperatur
                  * - Druckstatus
                  * - Meross Adaptersteuerung
                  ***********************/
                  
                  const printerId = '01S00C321500283';
                  
                  const baseBambu = `bambulab.0.${printerId}`;
                  const baseAMS   = '0_userdata.0.Bambulab.AMS';
                  const baseTemp  = '0_userdata.0.Bambulab.Temp';
                  const basePrint = '0_userdata.0.Bambulab.Print';
                  
                  const merossId  = 'meross.0.2303167546755151200348e1e9beebff.0';
                  const adapterId = 'system.adapter.bambulab.0';
                  
                  const trayNowId = `${baseBambu}.ams.tray_now`;
                  
                  const trayCount = 4;
                  const defaultColor = '#D3D3D3';
                  const refreshMs = 10000;
                  
                  const tempSources = {
                     bedActual: `${baseBambu}.bed_temper`,
                     bedTarget: `${baseBambu}.bed_target_temper`,
                     nozzleActual: `${baseBambu}.nozzle_temper`,
                     nozzleTarget: `${baseBambu}.nozzle_target_temper`
                  };
                  
                  const printSources = {
                     percent: `${baseBambu}.mc_percent`,
                     file: `${baseBambu}.gcode_file`,
                     state: `${baseBambu}.gcode_state`,
                     remaining: `${baseBambu}.mc_remaining_time`
                  };
                  
                  
                  // ------------------------------------------------------------
                  // Hilfsfunktionen
                  // ------------------------------------------------------------
                  
                  function create(id, def, type = null, role = 'state') {
                     if (!existsState(id)) {
                         createState(id, {
                             name: id.split('.').pop(),
                             type: type || typeof def,
                             role,
                             read: true,
                             write: true,
                             def
                         }, () => setState(id, def, true));
                     }
                  }
                  
                  function get(id) {
                     const state = getState(id);
                     return state ? state.val : undefined;
                  }
                  
                  function set(id, val) {
                     const state = getState(id);
                  
                     if (!state || state.val !== val) {
                         setState(id, val, true);
                     }
                  }
                  
                  function normalizeColor(raw) {
                     let c = String(raw ?? '').replace('#', '').trim();
                     c = c.replace(/[^0-9A-Fa-f]/g, '');
                  
                     if (c.length >= 6) {
                         return `#${c.substring(0, 6)}`.toUpperCase();
                     }
                  
                     return defaultColor;
                  }
                  
                  function getTextColor(color) {
                     return String(color).toLowerCase() === '#000000' ? '#FFFFFF' : '#000000';
                  }
                  
                  function formatTemp(v) {
                     const n = Number(v);
                     return isNaN(n) ? '-- °C' : `${Math.floor(n)} °C`;
                  }
                  
                  function parseRemaining(value) {
                     if (value === null || value === undefined || value === '') return 0;
                  
                     const s = String(value).trim();
                  
                     const hm = s.match(/^(\d+):(\d+)$/);
                     if (hm) return Number(hm[1]) * 60 + Number(hm[2]);
                  
                     if (!isNaN(Number(s))) return Number(s);
                  
                     return 0;
                  }
                  
                  function formatRemaining(value) {
                     const minutes = parseRemaining(value);
                     if (minutes <= 0) return '--';
                  
                     const h = Math.floor(minutes / 60);
                     const m = Math.floor(minutes % 60);
                  
                     return h > 0 ? `${h}h ${m}m` : `${m} min`;
                  }
                  
                  function finishTime(value) {
                     const minutes = parseRemaining(value);
                     if (minutes <= 0) return '--';
                  
                     const end = new Date(Date.now() + minutes * 60000);
                  
                     return end.toLocaleTimeString('de-DE', {
                         hour: '2-digit',
                         minute: '2-digit'
                     });
                  }
                  
                  
                  // ------------------------------------------------------------
                  // Datenpunkte erstellen
                  // ------------------------------------------------------------
                  
                  function createStates() {
                  
                     // AMS allgemein
                     create(`${baseAMS}.Aktiver_Tray`, 255, 'number', 'value');
                     create(`${baseAMS}.Farbe_aktiv`, defaultColor, 'string', 'value.color');
                     create(`${baseAMS}.AMS_Farbe_aktiv`, defaultColor, 'string', 'value.color');
                  
                     // Aktive Tray-Boolean-Datenpunkte nur AMS 0
                     create(`${baseAMS}.AMS0_Tray0`, false, 'boolean', 'indicator');
                     create(`${baseAMS}.AMS0_Tray1`, false, 'boolean', 'indicator');
                     create(`${baseAMS}.AMS0_Tray2`, false, 'boolean', 'indicator');
                     create(`${baseAMS}.AMS0_Tray3`, false, 'boolean', 'indicator');
                  
                     // AMS 0 Tray 0 bis 3
                     for (let tray = 0; tray < trayCount; tray++) {
                  
                         // Struktur mit .0.
                         create(`${baseAMS}.0.Farbe_Tray_${tray}`, defaultColor, 'string', 'value.color');
                         create(`${baseAMS}.0.Schriftfarbe_Tray_${tray}`, '#000000', 'string', 'value.color');
                         create(`${baseAMS}.0.Werte_Tray_${tray}`, '', 'string', 'text');
                  
                         // Einfache Struktur
                         create(`${baseAMS}.Farbe_Tray_${tray}`, defaultColor, 'string', 'value.color');
                         create(`${baseAMS}.Schriftfarbe_Tray_${tray}`, '#000000', 'string', 'value.color');
                         create(`${baseAMS}.Werte_Tray_${tray}`, '', 'string', 'text');
                     }
                  
                     // Temperaturen
                     create(`${baseTemp}.Ist_Druckbett`, '-- °C', 'string', 'text');
                     create(`${baseTemp}.Soll_Druckbett`, '-- °C', 'string', 'text');
                     create(`${baseTemp}.Ist_Duese`, '-- °C', 'string', 'text');
                     create(`${baseTemp}.Soll_Duese`, '-- °C', 'string', 'text');
                  
                     // Print
                     create(`${basePrint}.Fortschritt`, 0, 'number', 'value');
                     create(`${basePrint}.Datei`, '', 'string', 'text');
                     create(`${basePrint}.Status`, 'BEREIT', 'string', 'text');
                     create(`${basePrint}.Restzeit`, '--', 'string', 'text');
                     create(`${basePrint}.Fertig_um`, '--', 'string', 'text');
                  }
                  
                  
                  // ------------------------------------------------------------
                  // AMS Farben + Schriftfarben + Werte
                  // ------------------------------------------------------------
                  
                  function updateAMS() {
                  
                     for (let tray = 0; tray < trayCount; tray++) {
                         updateAmsTrayColor(tray);
                         updateAmsTrayWerte(tray);
                     }
                  
                     updateActiveAmsTray();
                  }
                  
                  
                  function updateAmsTrayColor(tray) {
                  
                     const sourceColorId = `${baseBambu}.ams.ams.0.tray.${tray}.tray_color`;
                  
                     const color = normalizeColor(get(sourceColorId));
                     const textColor = getTextColor(color);
                  
                     // Struktur mit .0.
                     set(`${baseAMS}.0.Farbe_Tray_${tray}`, color);
                     set(`${baseAMS}.0.Schriftfarbe_Tray_${tray}`, textColor);
                  
                     // Einfache Struktur
                     set(`${baseAMS}.Farbe_Tray_${tray}`, color);
                     set(`${baseAMS}.Schriftfarbe_Tray_${tray}`, textColor);
                  }
                  
                  
                  function updateAmsTrayWerte(tray) {
                  
                     const trayType = get(`${baseBambu}.ams.ams.0.tray.${tray}.tray_type`) ?? '';
                     const subBrands = get(`${baseBambu}.ams.ams.0.tray.${tray}.tray_sub_brands`) ?? '';
                  
                     // Nur Materialtyp und Filament-Untertyp
                     const wert = `${trayType};${subBrands}`;
                  
                     // Struktur mit .0.
                     set(`${baseAMS}.0.Werte_Tray_${tray}`, wert);
                  
                     // Einfache Struktur
                     set(`${baseAMS}.Werte_Tray_${tray}`, wert);
                  }
                  
                  
                  // ------------------------------------------------------------
                  // Aktives AMS / aktiver Tray
                  // ------------------------------------------------------------
                  
                  function updateActiveAmsTray() {
                  
                     const trayNow = Number(get(trayNowId));
                  
                     const trayStateNames = [
                         'AMS0_Tray0',
                         'AMS0_Tray1',
                         'AMS0_Tray2',
                         'AMS0_Tray3'
                     ];
                  
                     // Erst alle Trays auf false setzen
                     for (const name of trayStateNames) {
                         set(`${baseAMS}.${name}`, false);
                     }
                  
                     // Kein aktiver Tray oder ungültiger Wert
                     if (isNaN(trayNow) || trayNow === 255 || trayNow < 0 || trayNow > 3) {
                         set(`${baseAMS}.Aktiver_Tray`, 255);
                         set(`${baseAMS}.Farbe_aktiv`, defaultColor);
                         set(`${baseAMS}.AMS_Farbe_aktiv`, defaultColor);
                         return;
                     }
                  
                     // Aktiven Tray setzen
                     set(`${baseAMS}.Aktiver_Tray`, trayNow);
                     set(`${baseAMS}.${trayStateNames[trayNow]}`, true);
                  
                     const activeColor = get(`${baseAMS}.0.Farbe_Tray_${trayNow}`) || defaultColor;
                  
                     set(`${baseAMS}.Farbe_aktiv`, activeColor);
                     set(`${baseAMS}.AMS_Farbe_aktiv`, activeColor);
                  }
                  
                  
                  // ------------------------------------------------------------
                  // Temperaturen
                  // ------------------------------------------------------------
                  
                  function updateTemp() {
                     set(`${baseTemp}.Ist_Druckbett`, formatTemp(get(tempSources.bedActual)));
                     set(`${baseTemp}.Soll_Druckbett`, formatTemp(get(tempSources.bedTarget)));
                     set(`${baseTemp}.Ist_Duese`, formatTemp(get(tempSources.nozzleActual)));
                     set(`${baseTemp}.Soll_Duese`, formatTemp(get(tempSources.nozzleTarget)));
                  }
                  
                  
                  // ------------------------------------------------------------
                  // Druckstatus
                  // ------------------------------------------------------------
                  
                  function updatePrint() {
                     const percent = Number(get(printSources.percent)) || 0;
                     const file = String(get(printSources.file) ?? '');
                     const rawState = String(get(printSources.state) ?? '').toUpperCase();
                     const remainingRaw = get(printSources.remaining);
                     const remaining = parseRemaining(remainingRaw);
                  
                     let status = rawState || 'BEREIT';
                  
                     if (remaining > 0 && percent > 0 && percent < 100) {
                         status = 'DRUCKT';
                     } else if (percent >= 100) {
                         status = 'FERTIG';
                     } else if (
                         rawState.includes('FAIL') ||
                         rawState.includes('CANCEL') ||
                         rawState.includes('ABORT')
                     ) {
                         status = 'ABGEBROCHEN';
                     } else if (remaining <= 0 && percent <= 0) {
                         status = 'BEREIT';
                     }
                  
                     set(`${basePrint}.Status`, status);
                  
                     if (status === 'DRUCKT') {
                         set(`${basePrint}.Fortschritt`, percent);
                         set(`${basePrint}.Datei`, file);
                         set(`${basePrint}.Restzeit`, formatRemaining(remainingRaw));
                         set(`${basePrint}.Fertig_um`, finishTime(remainingRaw));
                     } else {
                         set(`${basePrint}.Fortschritt`, 0);
                         set(`${basePrint}.Datei`, '');
                         set(`${basePrint}.Restzeit`, '--');
                         set(`${basePrint}.Fertig_um`, '--');
                     }
                  }
                  
                  
                  // ------------------------------------------------------------
                  // Alles aktualisieren
                  // ------------------------------------------------------------
                  
                  function updateAll() {
                     updateAMS();
                     updateTemp();
                     updatePrint();
                  }
                  
                  
                  // ------------------------------------------------------------
                  // Trigger
                  // ------------------------------------------------------------
                  
                  // Meross Steckdose / BambuLab Adapter
                  on({ id: merossId, change: 'any' }, obj => {
                     const isOn = obj.state.val === true || obj.state.val === 1 || obj.state.val === 'true';
                  
                     setState(`${adapterId}.alive`, isOn);
                  
                     if (isOn) {
                         setTimeout(updateAll, 8000);
                     }
                  });
                  
                  
                  // AMS Änderungen nur AMS 0
                  on({
                     id: [
                         trayNowId,
                         new RegExp(`^bambulab\\.0\\.${printerId}\\.ams\\.ams\\.0\\.tray\\.[0-3]\\.`),
                         `${baseBambu}.sequence_id`
                     ],
                     change: 'any'
                  }, updateAMS);
                  
                  
                  // Temperatur Änderungen
                  on({
                     id: Object.values(tempSources),
                     change: 'any'
                  }, updateTemp);
                  
                  
                  // Druckstatus Änderungen
                  on({
                     id: Object.values(printSources),
                     change: 'any'
                  }, updatePrint);
                  
                  
                  // ------------------------------------------------------------
                  // Start
                  // ------------------------------------------------------------
                  
                  createStates();
                  
                  setTimeout(updateAll, 3000);
                  setInterval(updateAll, refreshMs);
                  

                  Intel NUC mit Iobroker

                  S 1 Antwort Letzte Antwort
                  0
                  • H helfi9999

                    @mdumbsky Hi habe ein wenig deine Blckly Skripte geändert in Java Skript vielleicht ist das was für dich:

                    /***********************
                    * BambuLab AMS 0 + TEMP + PRINT + MEROSS
                    * Komplett-Skript ohne AMS 1
                    *
                    * Enthält:
                    * - AMS 0 Tray 0 bis 3
                    * - Farben + Schriftfarben
                    * - Werte: Materialtyp;Filament-Untertyp
                    * - aktiver Tray
                    * - Temperatur
                    * - Druckstatus
                    * - Meross Adaptersteuerung
                    ***********************/
                    
                    const printerId = '01S00C321500283';
                    
                    const baseBambu = `bambulab.0.${printerId}`;
                    const baseAMS   = '0_userdata.0.Bambulab.AMS';
                    const baseTemp  = '0_userdata.0.Bambulab.Temp';
                    const basePrint = '0_userdata.0.Bambulab.Print';
                    
                    const merossId  = 'meross.0.2303167546755151200348e1e9beebff.0';
                    const adapterId = 'system.adapter.bambulab.0';
                    
                    const trayNowId = `${baseBambu}.ams.tray_now`;
                    
                    const trayCount = 4;
                    const defaultColor = '#D3D3D3';
                    const refreshMs = 10000;
                    
                    const tempSources = {
                       bedActual: `${baseBambu}.bed_temper`,
                       bedTarget: `${baseBambu}.bed_target_temper`,
                       nozzleActual: `${baseBambu}.nozzle_temper`,
                       nozzleTarget: `${baseBambu}.nozzle_target_temper`
                    };
                    
                    const printSources = {
                       percent: `${baseBambu}.mc_percent`,
                       file: `${baseBambu}.gcode_file`,
                       state: `${baseBambu}.gcode_state`,
                       remaining: `${baseBambu}.mc_remaining_time`
                    };
                    
                    
                    // ------------------------------------------------------------
                    // Hilfsfunktionen
                    // ------------------------------------------------------------
                    
                    function create(id, def, type = null, role = 'state') {
                       if (!existsState(id)) {
                           createState(id, {
                               name: id.split('.').pop(),
                               type: type || typeof def,
                               role,
                               read: true,
                               write: true,
                               def
                           }, () => setState(id, def, true));
                       }
                    }
                    
                    function get(id) {
                       const state = getState(id);
                       return state ? state.val : undefined;
                    }
                    
                    function set(id, val) {
                       const state = getState(id);
                    
                       if (!state || state.val !== val) {
                           setState(id, val, true);
                       }
                    }
                    
                    function normalizeColor(raw) {
                       let c = String(raw ?? '').replace('#', '').trim();
                       c = c.replace(/[^0-9A-Fa-f]/g, '');
                    
                       if (c.length >= 6) {
                           return `#${c.substring(0, 6)}`.toUpperCase();
                       }
                    
                       return defaultColor;
                    }
                    
                    function getTextColor(color) {
                       return String(color).toLowerCase() === '#000000' ? '#FFFFFF' : '#000000';
                    }
                    
                    function formatTemp(v) {
                       const n = Number(v);
                       return isNaN(n) ? '-- °C' : `${Math.floor(n)} °C`;
                    }
                    
                    function parseRemaining(value) {
                       if (value === null || value === undefined || value === '') return 0;
                    
                       const s = String(value).trim();
                    
                       const hm = s.match(/^(\d+):(\d+)$/);
                       if (hm) return Number(hm[1]) * 60 + Number(hm[2]);
                    
                       if (!isNaN(Number(s))) return Number(s);
                    
                       return 0;
                    }
                    
                    function formatRemaining(value) {
                       const minutes = parseRemaining(value);
                       if (minutes <= 0) return '--';
                    
                       const h = Math.floor(minutes / 60);
                       const m = Math.floor(minutes % 60);
                    
                       return h > 0 ? `${h}h ${m}m` : `${m} min`;
                    }
                    
                    function finishTime(value) {
                       const minutes = parseRemaining(value);
                       if (minutes <= 0) return '--';
                    
                       const end = new Date(Date.now() + minutes * 60000);
                    
                       return end.toLocaleTimeString('de-DE', {
                           hour: '2-digit',
                           minute: '2-digit'
                       });
                    }
                    
                    
                    // ------------------------------------------------------------
                    // Datenpunkte erstellen
                    // ------------------------------------------------------------
                    
                    function createStates() {
                    
                       // AMS allgemein
                       create(`${baseAMS}.Aktiver_Tray`, 255, 'number', 'value');
                       create(`${baseAMS}.Farbe_aktiv`, defaultColor, 'string', 'value.color');
                       create(`${baseAMS}.AMS_Farbe_aktiv`, defaultColor, 'string', 'value.color');
                    
                       // Aktive Tray-Boolean-Datenpunkte nur AMS 0
                       create(`${baseAMS}.AMS0_Tray0`, false, 'boolean', 'indicator');
                       create(`${baseAMS}.AMS0_Tray1`, false, 'boolean', 'indicator');
                       create(`${baseAMS}.AMS0_Tray2`, false, 'boolean', 'indicator');
                       create(`${baseAMS}.AMS0_Tray3`, false, 'boolean', 'indicator');
                    
                       // AMS 0 Tray 0 bis 3
                       for (let tray = 0; tray < trayCount; tray++) {
                    
                           // Struktur mit .0.
                           create(`${baseAMS}.0.Farbe_Tray_${tray}`, defaultColor, 'string', 'value.color');
                           create(`${baseAMS}.0.Schriftfarbe_Tray_${tray}`, '#000000', 'string', 'value.color');
                           create(`${baseAMS}.0.Werte_Tray_${tray}`, '', 'string', 'text');
                    
                           // Einfache Struktur
                           create(`${baseAMS}.Farbe_Tray_${tray}`, defaultColor, 'string', 'value.color');
                           create(`${baseAMS}.Schriftfarbe_Tray_${tray}`, '#000000', 'string', 'value.color');
                           create(`${baseAMS}.Werte_Tray_${tray}`, '', 'string', 'text');
                       }
                    
                       // Temperaturen
                       create(`${baseTemp}.Ist_Druckbett`, '-- °C', 'string', 'text');
                       create(`${baseTemp}.Soll_Druckbett`, '-- °C', 'string', 'text');
                       create(`${baseTemp}.Ist_Duese`, '-- °C', 'string', 'text');
                       create(`${baseTemp}.Soll_Duese`, '-- °C', 'string', 'text');
                    
                       // Print
                       create(`${basePrint}.Fortschritt`, 0, 'number', 'value');
                       create(`${basePrint}.Datei`, '', 'string', 'text');
                       create(`${basePrint}.Status`, 'BEREIT', 'string', 'text');
                       create(`${basePrint}.Restzeit`, '--', 'string', 'text');
                       create(`${basePrint}.Fertig_um`, '--', 'string', 'text');
                    }
                    
                    
                    // ------------------------------------------------------------
                    // AMS Farben + Schriftfarben + Werte
                    // ------------------------------------------------------------
                    
                    function updateAMS() {
                    
                       for (let tray = 0; tray < trayCount; tray++) {
                           updateAmsTrayColor(tray);
                           updateAmsTrayWerte(tray);
                       }
                    
                       updateActiveAmsTray();
                    }
                    
                    
                    function updateAmsTrayColor(tray) {
                    
                       const sourceColorId = `${baseBambu}.ams.ams.0.tray.${tray}.tray_color`;
                    
                       const color = normalizeColor(get(sourceColorId));
                       const textColor = getTextColor(color);
                    
                       // Struktur mit .0.
                       set(`${baseAMS}.0.Farbe_Tray_${tray}`, color);
                       set(`${baseAMS}.0.Schriftfarbe_Tray_${tray}`, textColor);
                    
                       // Einfache Struktur
                       set(`${baseAMS}.Farbe_Tray_${tray}`, color);
                       set(`${baseAMS}.Schriftfarbe_Tray_${tray}`, textColor);
                    }
                    
                    
                    function updateAmsTrayWerte(tray) {
                    
                       const trayType = get(`${baseBambu}.ams.ams.0.tray.${tray}.tray_type`) ?? '';
                       const subBrands = get(`${baseBambu}.ams.ams.0.tray.${tray}.tray_sub_brands`) ?? '';
                    
                       // Nur Materialtyp und Filament-Untertyp
                       const wert = `${trayType};${subBrands}`;
                    
                       // Struktur mit .0.
                       set(`${baseAMS}.0.Werte_Tray_${tray}`, wert);
                    
                       // Einfache Struktur
                       set(`${baseAMS}.Werte_Tray_${tray}`, wert);
                    }
                    
                    
                    // ------------------------------------------------------------
                    // Aktives AMS / aktiver Tray
                    // ------------------------------------------------------------
                    
                    function updateActiveAmsTray() {
                    
                       const trayNow = Number(get(trayNowId));
                    
                       const trayStateNames = [
                           'AMS0_Tray0',
                           'AMS0_Tray1',
                           'AMS0_Tray2',
                           'AMS0_Tray3'
                       ];
                    
                       // Erst alle Trays auf false setzen
                       for (const name of trayStateNames) {
                           set(`${baseAMS}.${name}`, false);
                       }
                    
                       // Kein aktiver Tray oder ungültiger Wert
                       if (isNaN(trayNow) || trayNow === 255 || trayNow < 0 || trayNow > 3) {
                           set(`${baseAMS}.Aktiver_Tray`, 255);
                           set(`${baseAMS}.Farbe_aktiv`, defaultColor);
                           set(`${baseAMS}.AMS_Farbe_aktiv`, defaultColor);
                           return;
                       }
                    
                       // Aktiven Tray setzen
                       set(`${baseAMS}.Aktiver_Tray`, trayNow);
                       set(`${baseAMS}.${trayStateNames[trayNow]}`, true);
                    
                       const activeColor = get(`${baseAMS}.0.Farbe_Tray_${trayNow}`) || defaultColor;
                    
                       set(`${baseAMS}.Farbe_aktiv`, activeColor);
                       set(`${baseAMS}.AMS_Farbe_aktiv`, activeColor);
                    }
                    
                    
                    // ------------------------------------------------------------
                    // Temperaturen
                    // ------------------------------------------------------------
                    
                    function updateTemp() {
                       set(`${baseTemp}.Ist_Druckbett`, formatTemp(get(tempSources.bedActual)));
                       set(`${baseTemp}.Soll_Druckbett`, formatTemp(get(tempSources.bedTarget)));
                       set(`${baseTemp}.Ist_Duese`, formatTemp(get(tempSources.nozzleActual)));
                       set(`${baseTemp}.Soll_Duese`, formatTemp(get(tempSources.nozzleTarget)));
                    }
                    
                    
                    // ------------------------------------------------------------
                    // Druckstatus
                    // ------------------------------------------------------------
                    
                    function updatePrint() {
                       const percent = Number(get(printSources.percent)) || 0;
                       const file = String(get(printSources.file) ?? '');
                       const rawState = String(get(printSources.state) ?? '').toUpperCase();
                       const remainingRaw = get(printSources.remaining);
                       const remaining = parseRemaining(remainingRaw);
                    
                       let status = rawState || 'BEREIT';
                    
                       if (remaining > 0 && percent > 0 && percent < 100) {
                           status = 'DRUCKT';
                       } else if (percent >= 100) {
                           status = 'FERTIG';
                       } else if (
                           rawState.includes('FAIL') ||
                           rawState.includes('CANCEL') ||
                           rawState.includes('ABORT')
                       ) {
                           status = 'ABGEBROCHEN';
                       } else if (remaining <= 0 && percent <= 0) {
                           status = 'BEREIT';
                       }
                    
                       set(`${basePrint}.Status`, status);
                    
                       if (status === 'DRUCKT') {
                           set(`${basePrint}.Fortschritt`, percent);
                           set(`${basePrint}.Datei`, file);
                           set(`${basePrint}.Restzeit`, formatRemaining(remainingRaw));
                           set(`${basePrint}.Fertig_um`, finishTime(remainingRaw));
                       } else {
                           set(`${basePrint}.Fortschritt`, 0);
                           set(`${basePrint}.Datei`, '');
                           set(`${basePrint}.Restzeit`, '--');
                           set(`${basePrint}.Fertig_um`, '--');
                       }
                    }
                    
                    
                    // ------------------------------------------------------------
                    // Alles aktualisieren
                    // ------------------------------------------------------------
                    
                    function updateAll() {
                       updateAMS();
                       updateTemp();
                       updatePrint();
                    }
                    
                    
                    // ------------------------------------------------------------
                    // Trigger
                    // ------------------------------------------------------------
                    
                    // Meross Steckdose / BambuLab Adapter
                    on({ id: merossId, change: 'any' }, obj => {
                       const isOn = obj.state.val === true || obj.state.val === 1 || obj.state.val === 'true';
                    
                       setState(`${adapterId}.alive`, isOn);
                    
                       if (isOn) {
                           setTimeout(updateAll, 8000);
                       }
                    });
                    
                    
                    // AMS Änderungen nur AMS 0
                    on({
                       id: [
                           trayNowId,
                           new RegExp(`^bambulab\\.0\\.${printerId}\\.ams\\.ams\\.0\\.tray\\.[0-3]\\.`),
                           `${baseBambu}.sequence_id`
                       ],
                       change: 'any'
                    }, updateAMS);
                    
                    
                    // Temperatur Änderungen
                    on({
                       id: Object.values(tempSources),
                       change: 'any'
                    }, updateTemp);
                    
                    
                    // Druckstatus Änderungen
                    on({
                       id: Object.values(printSources),
                       change: 'any'
                    }, updatePrint);
                    
                    
                    // ------------------------------------------------------------
                    // Start
                    // ------------------------------------------------------------
                    
                    createStates();
                    
                    setTimeout(updateAll, 3000);
                    setInterval(updateAll, refreshMs);
                    

                    S Nicht stören
                    S Nicht stören
                    stenmic
                    schrieb am zuletzt editiert von
                    #29

                    ich bin noch nicht ganz fertig, aber so wird meine aussehen.

                    IMG_1475.PNG

                    IMG_1476.PNG

                    1 Antwort Letzte Antwort
                    2

                    Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.

                    Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.

                    Mit deinem Input könnte dieser Beitrag noch besser werden 💗

                    Registrieren Anmelden
                    Antworten
                    • In einem neuen Thema antworten
                    Anmelden zum Antworten
                    • Älteste zuerst
                    • Neuste zuerst
                    • Meiste Stimmen


                    Support us

                    ioBroker
                    Community Adapters
                    Donate

                    518

                    Online

                    32.9k

                    Benutzer

                    83.0k

                    Themen

                    1.3m

                    Beiträge
                    Community
                    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                    ioBroker Community 2014-2025
                    logo
                    • Anmelden

                    • Du hast noch kein Konto? Registrieren

                    • Anmelden oder registrieren, um zu suchen
                    • Erster Beitrag
                      Letzter Beitrag
                    0
                    • Home
                    • Aktuell
                    • Tags
                    • Ungelesen 0
                    • Kategorien
                    • Unreplied
                    • Beliebt
                    • GitHub
                    • Docu
                    • Hilfe