Weiter zum Inhalt

Off Topic

3.2k Themen 50.2k Beiträge
Hier kann über alles geredet werden was sonst nirgendwo hinpasst

NEWS

Unterkategorien


  • 95 Themen
    2k Beiträge
    HomoranH
    @Thomas-Braun sagte: falls user genau in dem Zeitraum Adapter installiert haben, die eine ungepinnte axios-Version einbinden, dann könnte es sein, Kann man eigentlich die zusätzlichen npm-Module in der Javascript Instanz auch pinnen? Z.b. indem man eingibt modulName@1.2.3? Wie finde ich denn deren geladene Versionsnummern? Hab jetzt auch unter /opt/iobroker versucht mit npm list modulName, da kommt nur empty.
  • 257 4k
    257 Themen
    4k Beiträge
    S
    Ja, skvarel da hast du wohl recht, den Unterschied hab ich nicht gesehen, bei den Panels klappts bei mir auch. Nochmals vielen Dank für die Hilfe.
  • 148 3k
    148 Themen
    3k Beiträge
    R
    Ok, danke. Mit 644 hats geklappt.
  • Fragen und Hilfe zur externen SQL Datenbank

    1 5
    1 Themen
    5 Beiträge
    fuzzy1955F
    Teil 5: Verwenden der SQL-Daten in Diagrammen bzw. im VIS-2 Der Hauptzweck der Datenhistorisierung liegt natürlich in der grafischen bzw. tabellarischen Darstellung, um daraus mögliche Entscheidungen abzuleiten, etwa wo setzte ich beim Börsenstrompreis mein Bezugslimit. Eine einfache Möglichkeit zur grafischen Darstellung bieten die DIAGRAMME. Man wählt als Datenquellen die gewünschten SQL-Historisierungspunkte, stellt noch ein paar Dinge ein und … fertig. [image: 1770367644381-664a0f95-2fc3-48ae-babe-1a8ffafab1ad-image.png] Um das Ganze im VIS-2 anzuzeigen, nimmt man dort das Widget „Basic -IFrame“ und gibt bei Allgemein – Quelle den Link aus den Diagrammen an. [image: 1770367662940-281a33d1-fcdc-49bb-a3d9-c0fb7ea8ecd1-image.png] So kann man sich ein VIS-2-View nur für Diagramme bauen, bei der die gewünschte Art des Diagrammes angetippt wird: [image: 1770367682322-9328d9e4-3448-4e5a-8c92-8eeec3f2b52c-image.png] Die tabellarischen Darstellung im VIS-2 geschieht mit dem Widget „Basic Table“, bei dem man einen separaten Datenpunkt (Table Object ID) mit JSON-Daten befüllt. Dieses Beispiel zeigt Tages-, Monats- und Jahreswerte einer Strombilanz untereinander. [image: 1770367711812-00a9e22f-d74a-43e7-982f-0e35c37db84a-image.png] Die Datenpunkte dazu: { "alias.0.Diagrammdaten.StrombilanzJahre": { "common": { "name": "StrombilanzJahre", "desc": "Manuell erzeugt", "role": "state", "type": "json", "read": true, "write": true, "alias": { "id": "javascript.0.variables.j006" } }, "type": "state", "native": {}, "_id": "alias.0.Diagrammdaten.StrombilanzJahre", "acl": { "object": 1636, "state": 1636, "owner": "system.user.admin", "ownerGroup": "system.group.administrator" }, "val": "", "from": "system.adapter.admin.0", "user": "system.user.admin", "ts": 1768340995710, "ack": false }, "alias.0.Diagrammdaten.StrombilanzMonate": { "common": { "name": "StrombilanzMonate", "desc": "Manuell erzeugt", "role": "state", "type": "json", "read": true, "write": true, "alias": { "id": "javascript.0.variables.j005" } }, "type": "state", "native": {}, "_id": "alias.0.Diagrammdaten.StrombilanzMonate", "acl": { "object": 1636, "state": 1636, "owner": "system.user.admin", "ownerGroup": "system.group.administrator" }, "val": "", "from": "system.adapter.admin.0", "user": "system.user.admin", "ts": 1768340995710, "ack": false }, "alias.0.Diagrammdaten.StrombilanzTage": { "common": { "name": "StrombilanzTage", "desc": "Manuell erzeugt", "role": "state", "type": "json", "read": true, "write": true, "alias": { "id": "javascript.0.variables.j004" } }, "type": "state", "native": {}, "_id": "alias.0.Diagrammdaten.StrombilanzTage", "acl": { "object": 1636, "state": 1636, "owner": "system.user.admin", "ownerGroup": "system.group.administrator" }, "val": "", "from": "system.adapter.admin.0", "user": "system.user.admin", "ts": 1768340995710, "ack": false } } Mit einem Javascript werden die Datenpunkte zeitgesteuert befüllt. strSQL = "SELECT DATE_FORMAT (tag, '%Y-%m-%d') AS Tag, " + "ROUND(SUM(pv) / 1000.0,1) AS PV, " + "ROUND(AVG(akku)) AS Hausakku, " + "ROUND(SUM(haus) / 1000.0,1) AS Haus, " + "ROUND(SUM(eauto) / 1000.0,1) AS eAuto, " + "ROUND(SUM(gen) / 1000.0,1) AS Gen, " + "ROUND(SUM(nots) / 1000.0,1) AS Nots, " + "ROUND(SUM(gesamt) / 1000.0,1) AS gesamt, " + "ROUND(COUNT(autark)) AS autark " + "FROM iobroker.tagesstatistik " + "GROUP BY DATE_FORMAT (tag, '%Y-%m-%d') " + "ORDER BY DATE_FORMAT (tag, '%Y-%m-%d') desc;"; sendTo('sql.0', 'query', strSQL, function (result) { if (result.error) { console.error(result.error); } else { MyTrigger (idStrombilanzTage,JSON.stringify(result.result)); } }); --------------------------- Voila , das war die ganze Zauberei --------------------------- Anregungen, Fragen etc. bitte hier anhängen.
  • 272 Themen
    5k Beiträge
    M
    als Antwort wenn es keinen interessiert, es geht über esphome.
  • 187 5k
    187 Themen
    5k Beiträge
    NegaleinN
    @BananaJoe sagte in Proxmox Cluster oder HA: Hui, wieviel hast du denn? nur 4 :)
  • Fragen zu Docker-Installationen

    21 257
    21 Themen
    257 Beiträge
    haselchenH
    @0815_Peter Schön, dass es jetzt geht . Setz bitte den Thread hier auf [GELÖST].
  • 50 622
    50 Themen
    622 Beiträge
    Jey CeeJ
    Ein etwas größeres Projekt -> https://forum.iobroker.net/topic/84135/lan-cert-manager-lokale-domain-verwaltung-einfach
  • Wie mittels LUXTRONIK-Adapter Wassertemperatur einstellen?

    5
    3
    0 Stimmen
    5 Beiträge
    617 Aufrufe
    stolly82S
    Hey zusammen, ich habe ein Skript geschrieben, das die Steuerung der Wassertemperatur über MyUplink ermöglicht, da die Luxtronik Weboberfläche (ab Version 3.89.4) keine direkte Option dazu bietet. Der Plan ist, daraus später einen richtigen Adapter zu machen, aber hier ist schon einmal die Skriptversion zum Ausprobieren. Was macht das Skript? Die Luxtronik ab Version 3.89.4 kann MyUplink integrieren, und genau das nutzt dieses Skript aus. Das Skript erlaubt es euch, die Heizung und das Warmwasser über die MyUplink-Cloud zu steuern, und stellt alle Informationen zur Verfügung, die dort abgerufen werden können. Das bedeutet, ihr könnt die Temperatur direkt anpassen, ohne die Einschränkungen der normalen Weboberfläche. Mehr Informationen zu MyUplink findet ihr hier: MyUplink Cloud – Alpha Innotec So probiert ihr das Skript aus: Öffnet den IoBroker > JavaScript Adapter > Neu > JavaScript > Hinzufügen. Fügt das Skript ein. Tragt eure MyUplink-Zugangsdaten ein. Startet das Skript – und schon seid ihr einsatzbereit! Funktionsumfang Heizung & Warmwasser: Ihr könnt die gewünschten Temperaturen einstellen. Informationsabruf: Alle relevanten Daten, die MyUplink zur Verfügung stellt, werden abgerufen und angezeigt. Falls ihr das Skript ausprobiert, würde ich mich sehr über euer Feedback freuen. Viel Spaß damit! // Konfigurationseinstellungen const CONFIG = { email: 'EMAIL@MYMAIL.DE', password: 'GEHEIM', clientId: 'My-Uplink-iOS', clientSecret: '992EFE7C-9CDC-435B-8BA3-2EF8E81BEF14', interval: 30000, // Standardintervall in Millisekunden für wiederkehrende Abfragen intervalFunctions: [ 'getWeatherTileData', 'getAndCreateMenu' ] }; const axios = require('axios'); class MyUplinkAdapter { constructor() { this.token = null; this.userData = {}; // Hier werden die Benutzerdaten gespeichert this.devices = {}; // Hier werden die Gerätedaten gespeichert this.groups = []; // Hier werden die Gruppendaten gespeichert this.failedRequests = []; // Warteschlange für fehlgeschlagene Anfragen log('Konstruktor von MyUplinkAdapter wurde aufgerufen!', 'info'); // Initialisieren des Verbindungsstatus setObject('myUplink.info.connection', { type: 'state', common: { name: 'API-Verbindungsstatus', type: 'boolean', role: 'indicator.connected', read: true, write: false }, native: {} }); setState('myUplink.info.connection', { val: false, ack: true }); } // Authentifizierungsmethode authenticate() { log("Starte Authentifizierung...", 'info'); log(`Authentifizierungsparameter: email=${CONFIG.email}, clientId=${CONFIG.clientId}`, 'debug'); return axios.post('https://internalapi.myuplink.com/v2/users/validate', { email: CONFIG.email, password: CONFIG.password }, { headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Accept-Language': 'de-DE' } }) .then(response => { log("Benutzer validiert. Antwort: " + JSON.stringify(response.data), 'debug'); const validationData = response.data; if (validationData.id) { this.userData = validationData; // Speichert die Benutzerdaten log(`Authentifizierung erfolgreich. Benutzer-ID: ${validationData.id}`, 'info'); setState('myUplink.info.connection', { val: true, ack: true }); // Verbindung erfolgreich return this.getAccessToken(validationData.id); } else { log("Fehlende ID im Validierungsschritt. Antwort: " + JSON.stringify(validationData), 'error'); throw new Error('User validation failed: Missing ID'); } }) .catch(error => { this.handleError(error); setState('myUplink.info.connection', { val: false, ack: true }); // Verbindung fehlgeschlagen throw error; }); } // Methode zum Abrufen des Access Tokens getAccessToken(userId) { log("Abrufen des Access Tokens...", 'info'); log(`Tokenparameter: clientId=${CONFIG.clientId}, userId=${userId}`, 'debug'); return axios.post('https://internalapi.myuplink.com/oauth/token', `password=${encodeURIComponent(CONFIG.password)}&client_secret=${CONFIG.clientSecret}&grant_type=password&client_id=${CONFIG.clientId}&username=${encodeURIComponent(CONFIG.email)}`, { headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'Authorization': `Bearer ${userId}` } } ) .then(response => { log("Token erfolgreich erhalten. Antwort: " + JSON.stringify(response.data), 'debug'); const tokenData = response.data; if (tokenData.access_token) { this.token = tokenData.access_token; log(`Access-Token erfolgreich gespeichert.`, 'info'); return tokenData; } else { log("Fehlender Access-Token in der Antwort: " + JSON.stringify(tokenData), 'error'); throw new Error('Access token not received'); } }) .catch(error => { this.handleError(error); throw error; }); } // Methode zum Speichern der Benutzerdaten saveUserData() { return this.ensureTokenIsValid().then(() => { log("Speichern der Benutzerdaten...", 'info'); const userUrl = 'https://internalapi.myuplink.com/v2/users/me'; log(`Anfrage-URL für Benutzerdaten: ${userUrl}`, 'debug'); return axios.get(userUrl, { headers: { 'Authorization': `Bearer ${this.token}`, 'Accept': 'application/json' } }) .then(response => { log("Benutzerdaten erfolgreich abgerufen. Antwort: " + JSON.stringify(response.data), 'debug'); this.userData = response.data; // Dynamische Erstellung der Datenpunkte in myUplink.users und Setzen der Werte Object.keys(this.userData).forEach(key => { if (typeof this.userData[key] === 'object' && this.userData[key] !== null) { Object.keys(this.userData[key]).forEach(subKey => { const stateId = `myUplink.User.${key}.${subKey}`; setObject(stateId, { type: 'state', common: { name: `${key} ${subKey}`, type: typeof this.userData[key][subKey], read: true, write: false } }); setState(stateId, { val: this.userData[key][subKey], ack: true }); }); } else { const stateId = `myUplink.User.${key}`; setObject(stateId, { type: 'state', common: { name: key, type: typeof this.userData[key], read: true, write: false } }); setState(stateId, { val: this.userData[key], ack: true }); } }); return this.userData; }) .catch(error => { this.handleError(error); throw error; }); }); } // Methode für das Abrufen der Wetterdaten getWeatherTileData() { return this.ensureTokenIsValid().then(() => { const group = this.groups.find(g => g.id); // Nimmt die erste gültige Gruppe aus den gespeicherten Gruppendaten if (!group || !group.id) { log('Keine gültige Group ID gefunden.', 'error'); throw new Error('No valid Group ID found.'); } const groupId = group.id; const fetchWeatherData = () => { log("Abrufen der Wetterdaten...", 'info'); const weatherUrl = `https://internalapi.myuplink.com/v2/groups/${groupId}/weather-tile-data`; log(`Anfrage-URL für Wetterdaten: ${weatherUrl}`, 'debug'); return axios.get(weatherUrl, { headers: { 'Authorization': `Bearer ${this.token}`, 'Accept': 'application/json' } }) .then(response => { log("Wetterdaten erfolgreich abgerufen. Antwort: " + JSON.stringify(response.data), 'debug'); const weatherData = response.data; // Dynamische Erstellung der Datenpunkte in myUplink.Weather und Setzen der Werte const basePath = `myUplink`; Object.keys(weatherData).forEach(key => { if (typeof weatherData[key] === 'object' && weatherData[key] !== null) { if (Array.isArray(weatherData[key])) { weatherData[key].forEach((item, index) => { Object.keys(item).forEach(subKey => { const stateId = `${basePath}.Weather.${key}[${index}].${subKey}`; setObject(stateId, { type: 'state', common: { name: `${key} ${subKey}`, type: typeof item[subKey], read: true, write: false } }); setState(stateId, { val: item[subKey], ack: true }); }); }); } else { Object.keys(weatherData[key]).forEach(subKey => { const stateId = `${basePath}.Weather.${key}.${subKey}`; setObject(stateId, { type: 'state', common: { name: `${key} ${subKey}`, type: typeof weatherData[key][subKey], read: true, write: false } }); setState(stateId, { val: weatherData[key][subKey], ack: true }); }); } } else { const stateId = `${basePath}.Weather.${key}`; setObject(stateId, { type: 'state', common: { name: key, type: typeof weatherData[key], read: true, write: false } }); setState(stateId, { val: weatherData[key], ack: true }); } }); return weatherData; }) .catch(error => { this.handleError(error, fetchWeatherData); }); }; // Erstmaliger Aufruf und Intervall einrichten fetchWeatherData(); setInterval(fetchWeatherData, CONFIG.interval); }); } // Methode zum Sicherstellen, dass der Token noch gültig ist ensureTokenIsValid() { if (!this.token) { log("Token ist nicht vorhanden oder ungültig. Hole neuen Token...", 'warn'); return this.authenticate(); } return Promise.resolve(); } // Methode zum Abrufen der Gruppendaten getGroups() { return this.ensureTokenIsValid().then(() => { log("Abrufen der Gruppendaten...", 'info'); const groupsUrl = 'https://internalapi.myuplink.com/v2/groups/me'; log(`Anfrage-URL für Gruppendaten: ${groupsUrl}`, 'debug'); return axios.get(groupsUrl, { headers: { 'Authorization': `Bearer ${this.token}`, 'Accept': 'application/json' } }) .then(response => { log("Gruppendaten erfolgreich abgerufen. Antwort: " + JSON.stringify(response.data), 'debug'); this.groups = response.data.groups || []; // Speichert die Gruppendaten this.devices = this.groups.flatMap(group => group.devices) || []; // Speichert die Gerätedaten this.createObjectsFromGroupsAndDevices(); return this.groups; }) .catch(error => { this.handleError(error); throw error; }); }); } // Methode zum Erstellen der Baumstruktur in myUplink createObjectsFromGroupsAndDevices() { log("Erstelle Objekte für Gruppen und Geräte...", 'info'); this.groups.forEach(group => { const groupId = group.id; group.devices.forEach(device => { const deviceId = device.id; const groupPath = `myUplink.System.${groupId}.${deviceId}`; // Erstellt das Geräteobjekt innerhalb der Gruppe setObject(groupPath, { type: 'device', common: { name: device.name || 'Unbenanntes Gerät', desc: device.description || '' }, native: device }); }); }); log("Objekterstellung abgeschlossen.", 'info'); } // Methode zum Abrufen der Menüstruktur async getAndCreateMenu(menuId = 0, basePath = `myUplink`) { try { const device = this.groups.flatMap(group => group.devices).find(device => device.id); if (!device || !device.id) { log('Keine gültige Device ID gefunden.', 'error'); throw new Error('No valid Device ID found.'); } const menuUrl = `https://internalapi.myuplink.com/v3/devices/${device.id}/menu/${menuId}`; const response = await axios.get(menuUrl, { headers: { 'Authorization': `Bearer ${this.token}`, 'Accept': 'application/json' } }); const menuData = response.data; if (menuData.rows && menuData.rows.length > 0) { for (const row of menuData.rows) { let name = row.text?.text || `Menü_${row.id}`; name = this.normalizeName(name); // Normalisieren von Umlauten const path = `${basePath}.${name}`; // Falls es ein weiterer Menü-Link ist, rufe das nächste Menü ab if (row.type === 'uilink') { setObject(path, { type: 'channel', common: { name: name, desc: `Menü ID: ${row.id}` }, native: row }); await this.getAndCreateMenu(row.id, path); } // Falls es ein Parameter ist, erstelle das Parameter-Objekt if (row.type === 'uiinfoparameter' || row.type === 'uinumerical' || row.type === 'uidropdown' || row.type === 'uiboolean') { this.createParameterObject(path, row); } } } } catch (error) { this.handleError(error); } } // Methode zum Erstellen eines Parameter-Objekts createParameterObject(path, parameter) { const parameterName = parameter.text?.text || `Parameter_${parameter.parameterId}`; let value = parameter.value?.integerValue ?? parameter.value?.stringValue ?? null; let adjustedValue = value; // Divisor anwenden, falls vorhanden und nur auf den Wert im Objekt selbst if (parameter.metadata?.divisor) { if (typeof value === 'number') { adjustedValue = value / parameter.metadata.divisor; } } // Wert als Text anzeigen, falls enumValues vorhanden sind const states = {}; if (parameter.metadata?.enumValues && parameter.metadata.enumValues.length > 0) { parameter.metadata.enumValues.forEach(ev => { states[ev.value] = ev.text; }); adjustedValue = value; } // Setze den Objekt-Typ je nach Parameter-Typ const commonType = parameter.metadata?.variableType?.toLowerCase() || 'mixed'; const role = parameter.type === 'uiboolean' ? 'switch' : 'text'; setObject(path, { type: 'state', common: { name: parameterName, type: commonType, unit: parameter.metadata?.unit || '', read: true, write: parameter.metadata?.isWritable || false, role: role, states: Object.keys(states).length > 0 ? states : undefined, min: parameter.metadata?.minValue && parameter.metadata.minValue !== 0 ? parameter.metadata.minValue / (parameter.metadata.divisor || 1) : undefined, max: parameter.metadata?.maxValue && parameter.metadata.maxValue !== 0 ? parameter.metadata.maxValue / (parameter.metadata.divisor || 1) : undefined, step: parameter.metadata?.change ? parameter.metadata.change / (parameter.metadata.divisor || 1) : undefined }, native: parameter }); // Setze den Wert des Parameters als Zahl oder Enum-Wert setState(path, { val: typeof adjustedValue === 'number' ? adjustedValue : value, ack: true }); // Lausche auf Änderungen des Werts, um die PUT-Anfrage zu senden if (parameter.metadata?.isWritable) { on({id: path, change: 'ne'}, (obj) => { // 'ne' bedeutet, nur nicht bestätigte Änderungen lauschen if (obj.state.ack) { return; // Wenn die Änderung von der API bestätigt wurde, ignoriere sie } let newValue = obj.state.val; const divisor = parameter.metadata?.divisor || 1; const minValue = typeof parameter.metadata?.minValue !== 'undefined' && parameter.metadata.minValue !== 0 ? parameter.metadata.minValue / divisor : undefined; const maxValue = typeof parameter.metadata?.maxValue !== 'undefined' && parameter.metadata.maxValue !== 0 ? parameter.metadata.maxValue / divisor : undefined; const change = parameter.metadata?.change ? parameter.metadata.change / divisor : undefined; // Werte begrenzen und anpassen if (typeof minValue !== 'undefined' && newValue < minValue) { newValue = minValue; } if (typeof maxValue !== 'undefined' && newValue > maxValue) { newValue = maxValue; } if (typeof change !== 'undefined') { newValue = Math.round(newValue / change) * change; } const adjustedValueForPut = newValue * divisor; let currentPath = path; let menuId = null; while (!menuId && currentPath.includes('.')) { currentPath = currentPath.substring(0, currentPath.lastIndexOf('.')); const currentObject = getObject(currentPath); if (currentObject?.native?.id) { menuId = currentObject.native.id; } } if (menuId) { this.updateParameterValue(menuId, parameter.parameterId, adjustedValueForPut, parameter.metadata?.unit || '', path, newValue); } else { log(`Fehler: Menü-ID für Pfad ${path} nicht gefunden.`, 'error'); } }); } } // Methode zum Normalisieren von Umlauten normalizeName(name) { return name .replace(/ä/g, 'ae') .replace(/ö/g, 'oe') .replace(/ü/g, 'ue') .replace(/ß/g, 'ss') .replace(/[^a-zA-Z0-9]/g, '_'); } // Methode zur Aktualisierung der Parameterwerte (PUT-Call) updateParameterValue(menuId, parameterId, value, unit = "", path, newValue) { const device = this.groups.flatMap(group => group.devices).find(device => device.id); if (!device || !device.id) { log('Keine gültige Device ID gefunden.', 'error'); throw new Error('No valid Device ID found.'); } const updateUrl = `https://internalapi.myuplink.com/v2/devices/${device.id}/menu/${menuId}/rawpoints/${parameterId}`; log(`Sende PUT-Anfrage an URL: ${updateUrl} mit Wert: ${value} und Einheit: ${unit}`, 'info'); return axios.put(updateUrl, { value: value, unit: unit }, { headers: { 'Authorization': `Bearer ${this.token}`, 'Content-Type': 'application/json' } }) .then(response => { log(`Parameter erfolgreich aktualisiert: ${JSON.stringify(response.data)}`, 'debug'); setState(path, { val: newValue, ack: true }); // Bestätigt den Wert im Objekt }) .catch(error => { this.handleError(error, () => this.updateParameterValue(menuId, parameterId, value, unit, path, newValue)); }); } // Fehlerbehandlungs-Methode handleError(error, retryCallback = null) { if (error.response) { log('Fehler-Antwortdaten: ' + JSON.stringify(error.response.data, null, 2), 'error'); log('HTTP-Statuscode: ' + error.response.status, 'error'); if (error.response.status === 401) { log('Token abgelaufen, erneuere den Token...', 'warn'); this.authenticate().then(() => { if (retryCallback) { retryCallback(); } }); } } setState('myUplink.info.connection', { val: false, ack: true }); // Verbindung fehlgeschlagen } } // Beispiel für die Verwendung der MyUplinkAdapter-Klasse (alle Logs als Fehler oder Warnungen) log("Starte die Authentifizierung...", 'info'); const adapter = new MyUplinkAdapter(); adapter.authenticate() .then(() => adapter.getGroups()) .then(groups => { log("Gruppendaten empfangen: " + JSON.stringify(groups), 'debug'); log("Gerätedaten empfangen: " + JSON.stringify(adapter.devices), 'debug'); return adapter.saveUserData(); }) .then(userData => { log("Benutzerdaten gespeichert: " + JSON.stringify(userData), 'info'); return adapter.getWeatherTileData(); }) .then(weatherData => { log("Wetterdaten empfangen: " + JSON.stringify(weatherData), 'info'); }) .then(() => adapter.getAndCreateMenu()) .then(() => { log('Menüstruktur erfolgreich erstellt.', 'info'); }) .then(() => { // Dynamisches Registrieren der Intervall-Funktionen CONFIG.intervalFunctions.forEach(funcName => { if (typeof adapter[funcName] === 'function') { setInterval(() => { adapter[funcName](); }, CONFIG.interval); log(`${funcName} wurde als Intervallfunktion registriert.`, 'info'); } else { log(`Funktion ${funcName} existiert nicht im Adapter.`, 'error'); } }); }) .catch(err => { log('Allgemeiner Fehler: ' + (err.message || "Keine Fehlermeldung verfügbar"), 'error'); }); log("Ende des Skripts erreicht.", 'info');
  • Partitionsgröße automatisch erweitern deaktivieren

    Verschoben
    16
    0 Stimmen
    16 Beiträge
    980 Aufrufe
    mickymM
    Nun @ro75 sagte in Partitionsgröße automatisch erweitern deaktivieren: Für was diesen Murks? Nun ich versteh das schon - ich habe meine Partition auch minimal verkleinert, damit die images auf unterschiedliche Fabrikate von SD Karten passen. Installiere Dir parted und resize2fs. Mit parted verkleinere die Partition, anschließend das Dateisystem mit resize2fs anpassen.
  • Yahka Thermostat mit Temperatursensor u. Steckdose erstellen

    Verschoben
    5
    0 Stimmen
    5 Beiträge
    289 Aufrufe
    paul53P
    @dody0007 sagte: Die Steckdose soll dann einschalten und wenn die Zieltemp. erreicht ist, wieder ausschalten. Dafür benötigst du einen eigenen Datenpunkt für den Sollwert und einen Zweipunkt-Regler (Skript).
  • Empfehlung 19" Server gesucht

    30
    0 Stimmen
    30 Beiträge
    2k Aufrufe
    BananaJoeB
    @negalein sagte in Empfehlung 19" Server gesucht: War nur so ein Gedankt, da ich die sehr günstig bekommen hätte. naja, deshalb liegt mein Kauf hier ja auch rum, schön billig sind die ja. Ich habe diese Erfahrung also auch mit Geld erkauft. Ich hatte den in der Testumgebung in der Firma im Einsatz, da ist der Stromverbrauch "egal" bzw. fallen ein paar hundert Watt mehr oder weniger schlicht nicht auf.
  • HM-IP Heizkörperthermostat-Display sehr blass / schwach

    Verschoben
    7
    0 Stimmen
    7 Beiträge
    499 Aufrufe
    Samson71S
    @timmss sagte in HM-IP Heizkörperthermostat-Display sehr blass / schwach: @samson71 Das könnte sein ja, wobei die frisch angebaut sind und vor nichtmal einem Jahr bestellt :( Dann wäre ja noch Garantie drauf. Sollte sich der Blickwinkel nicht als Grund zeigen, dann würde ich das direkt reklamieren.
  • Samsung Tab A8 - Akku

    7
    1
    0 Stimmen
    7 Beiträge
    382 Aufrufe
    NegaleinN
    @samson71 sagte in Samsung Tab A8 - Akku: Die Netzteile meiner 4 Wandtablets werden von Schaltaktoren ein- und ausgeschaltet Hätte ich vor. Muss aber erst Platz finden. Wird wohl hinter dem Tablet eine tiefe UP werden.
  • Roborock S7 einen bestimmten Raum Reinigung anstarten

    1
    0 Stimmen
    1 Beiträge
    179 Aufrufe
    Niemand hat geantwortet
  • Gesperrter Thread: "Linux bändigen"

    29
    0 Stimmen
    29 Beiträge
    1k Aufrufe
    K
    @oliverio Bei den Ubuntuusers schaue ich auch zuerst nach, wenn ich mal eine Linux-Frage habe. Dort wird meist sehr gut erklärt - auch anhand von Beispielen. Hat mir i.a. besser geholfen als manpage.
  • Linux-Tipps: USB-Serial und ESP-Programmierung

    2
    2
    1 Stimmen
    2 Beiträge
    480 Aufrufe
    MartinPM
    Hier noch als Nachtrag eine "sinnvolle" Anwendung von cu, wenn das (fast) fertig programmierte ESP-Device in der Nähe des Proxmox Servers steht. Dann kann man für Feinschliff schön mitlesen, was passiert. USB-Device zu einem "Spiel" Debian--LXC durchreichen, und Kontrollausgaben des ESP32 anzeigen lassen (kommen alle 10 Sekunden) martin@DebianTest:~$ cu -s 115200 -l /dev/ttyACM0 Connected. Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.87 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.69 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.81 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.81 21.87 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.87 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.55 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.25 24.75 21.87 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.54 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.24 24.69 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.54 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.24 24.75 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.54 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.24 24.75 21.94 SollT 18.70 WiFi 1 MQTT 1 ok Difftemp:3.54 Hyst:0.15 ventState:0 pwmActual:0 Tmprtrs(22.24 24.75 21.87 SollT 18.70 WiFi 1 MQTT 1 ok
  • Kaco Powador mit RS485 zu MQTT

    Verschoben
    4
    0 Stimmen
    4 Beiträge
    261 Aufrufe
    Samson71S
    @hanshiasl sagte in Kaco Powador mit RS485 zu MQTT: Ich beziehe mich hier auf einen älteren Thread: Mir ist sehr wohl bewusst worauf sich das bezieht. Trotzdem kann niemand helfen ohne dedizierte Infos. Insofern ändert das nichts an meiner Antwort. Ich meinte natürlich Screenshots vom entsprechenden ioBroker-Adapter, da ich annahm dass es um ein MQTT-Problem im Zusammenhang mit ioBroker geht. Im Moment schwant mir aber, dass Du ioBroker überhaupt nicht nutzt. Dann hat das hier auch nichts in der Rubrik "ioBroker Allgemein" zu suchen, sondern gehört nach "Off Topic", weil es eben kein ioBroker-Problem ist, bzw. mit diesem nichts zu tun hat. Da helfen dann vermutlich auch weder Log-Einträge von Mosquitto noch vom speziellen Raspi. Der angesprochene User hat auch exakt nur diesen einen Beitrag überhaupt geschrieben und war seit mehr als anderthalb Jahren nicht mehr online. Von daher würde ich mir da eher keine großen Hoffnungen machen.
  • [Gelöst] Problem mit WLAN-Mesh-Netzwerk (Fritzboxen)

    11
    0 Stimmen
    11 Beiträge
    1k Aufrufe
    H
    @hans_999 said in Problem mit Mesh-Netzwerk (Fritzboxen): Irgendwie schaut es aus, als ob da ein Filter in der Meshverbindung zuschlägt. Aber ich habe nichts in der FB gefunden, was hier falsch parametriert sein könnte. Hat jemand eine Idee, wo ich suchen könnte oder gar Lösung? Mittlerweile hatte ich die Muße einmal die Einstellungen in der FB durchzuprobieren. Den beschriebenen Effekt konnte ich mit folgender Einstellung an der 1. Fritzbox (Master Master) "wegbekommen" WLAN - Sicherheit - Verschlüsselung - Aktive WLAN-Geräte dürfen untereinander kommunizieren erlauben Das gefällt mir zwar nicht so ganz, denn damit kann jedes mobile Gerät im Netz auf die anderen mobilen Geräte zugreifen. Aber im Nachgang klingt es logisch: Die Meshverbindung bindet ein WLAN-Gerät (Mesh-Partner) ein und dem Smartphone wird der Zugriff auf den Mesh-Partner nicht erlaubt. Aber über LAN gab es diese Einschränkung nicht.
  • Ubuntu 24.04 LTS

    11
    1 Stimmen
    11 Beiträge
    1k Aufrufe
    NegaleinN
    @lobomau sagte in Ubuntu 24.04 LTS: das LXC-Backup bringt dich doch genau dahin wo du vorher warst, also zum Ubuntu 22.04. dachte ich mir. ioB ist kein Problem. Bei einigen muss ich erst forschen, wie da ein Backup&Restore möglich ist.
  • Homekit-controller lässt sich nicht installieren

    Verschoben
    28
    0 Stimmen
    28 Beiträge
    3k Aufrufe
    H
    @sirdrinsalot Ich habe leider ebenfalls das Problem unter Windows und wäre für hilfreiche Tipps sehr dankbar! Visual Studio 2017 habe ich auch installiert. Wie passt man die Python Pfade entsprechend an? Dank Dir schon vorab!
  • LinuxTipp: "Mittlere Maustaste" wegkonfigurieren.

    2
    2
    0 Stimmen
    2 Beiträge
    215 Aufrufe
    MartinPM
    @martinp Heute getestet, funktionert - nach dem Boot ist die mittlere Maustaste unter dem Scrollrad ohne mein Zutun durch das beim Start automatisch ausgeführte Script wegkonfiguriert...
  • Warnung vor dem Linux Mint Upgrade auf 22.0

    2
    0 Stimmen
    2 Beiträge
    687 Aufrufe
    MartinPM
    So, ein kleines Update - vorher fungierte eine 250 GByte SATA-SSD als Systemplatte, jetzt habe ich kurzentschlossen eine 500 GByte SATA-SSD beim Prime Day geschossen. Mint 22.0 Live USB-Stick gebastelt, Boot-Reihenfolge umgestellt und 22.0 auf der neuen Platte Installiert, Linux Mint 22.0 bootet problemlos, die alte Systemplatte ist soweit unversehrt, dass ich jetzt nach und nach die Daten migrieren kann... Drucker/Scanner läuft, Mails gehen wieder Browser Profil ist migriert, Banking mit Hibiscus geht dank regelmäßiger Backups, ohne dass ich da Daten erneut von der Bank herunter laden musste ... Schrittweise weiter machen - die zweite SSD frisst ja kein Brot ...
  • 2024 noch mit Zigbee starten oder auf Thread setzen?

    10
    0 Stimmen
    10 Beiträge
    2k Aufrufe
    Jey CeeJ
    @black-falcon87 wirkliche Nachteile wirst du erstmal keine haben. Einzig das Thema Umzug, wenn du dann mal wechselst, könnte man als Nachteil betrachten. Da du dann im ioBroker deine Skripte und Visualisierung anpassen musst weil sich die Datenpunkte ändern. Mit Alias lässt sich das auf ein minimum reduzieren. Das zweite wäre das viele Geräte zum anlernen Zurückgesetzt werden, was bedeutet das du Zigbee Gruppen sofern du welche eingerichtet hast, neu machen musst. Mach dir doch einfach mal Gedanken welche Geräte du so in Zukunft anschaffen möchtest und schau ob die von der Hue Bridge Unterstützt werden. Wenn schon jetzt klar ist das es in naher Zukunft eine andere Lösung braucht, kannst du auch gleich wechseln.
  • iobroker hochverfügbar

    Verschoben
    82
    1 Stimmen
    82 Beiträge
    13k Aufrufe
    m1k3f15hM
    @apollon77 So hab ich das noch nie gesehen :) das ist ein guter Ansatz :) mike
  • crontab funktioniert nicht (Gelöst)

    14
    0 Stimmen
    14 Beiträge
    1k Aufrufe
    MichaelFM
    Danke an alle, Funktioniert jetzt. Lösung war die Berechtigung. Grüße
  • Fire TV Fernseher - Erfahrungen

    18
    0 Stimmen
    18 Beiträge
    2k Aufrufe
    stolly82S
    Hey, ist bei dem Thema schon eine Möglichkeit, dass man den Status des TV's abgreift? Also TV ist an, Screen ist an,... Waipu wird geschaut,... Ich hatte bei mir einen Samsung TV der wenn er an war mit dem WLAN verbunden hat, so dass ich das abgreifen konnte über den Radar Adapter. Hier sehe ich im Alexa2 Adapter leider nichts und habe aktuell auch nichts was wirklich funktioniert um die abzugreifen.
  • IKEA Kalax Regal beleuchtet mit WLED

    Verschoben beleuchtung esp32 esp8266 ideen kalax regal vorschlag wled ws2812
    3
    2
    0 Stimmen
    3 Beiträge
    442 Aufrufe
    Basti97B
    @homoran Der Beitrag handelt um das Dekorative Beleuchten mit WS2812 Strips für das Kalax Regal von IKEA. Es ist erstmals als Anregung gedacht ob jemand auch daran interessiert ist und ob jemand auf das gleiche Problem gestoßen ist (siehe oben). Für mich ist es wichtig eine "einfache Möglichkeit" für jeden SmartHomer zu finden und natürlich für mich da ich noch zwei Regale habe die Plug and Play ist. Und ja wenn ich eine einfache Möglichkeit gefunden habe dann könnte ich vielleicht den Rest hier für geringes Geld anbieten weiß ich aber noch nicht).

570

Online

32.7k

Benutzer

82.6k

Themen

1.3m

Beiträge