Skip to content

Off Topic

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

NEWS

Unterkategorien


  • 88 Themen
    2k Beiträge
    FabioF
    @Thomas-Braun sagte in nodesource-Repo - OpenPGP signature verification failed: kann nun die alte Signatur ersetzen lassen. Dazu einfach per iob nodejs-update 22 vielen Dank @thomas-braun hat super geklappt. ;-) Herzliche Grüße Fabio
  • 256 4k
    256 Themen
    4k Beiträge
    mickemupM
    @marcel-drzal sagte in grafana Windgeschwindigkeit richtig anzeigen lassen: Auch die Stellantriebe werden nicht richtig angezeigt. Was wird denn da nicht richtig angezeigt?
  • 145 3k
    145 Themen
    3k Beiträge
    L
    @mickemup @homoran Der Adapter schreibt ohne zu mucken in die Datenbank. Egal, welche Einstellungen ich darin vornehme. Außer bei der Abweichungsprüfung Werte, die nicht auftreten können (2...). Ich vermute, die Datentypmischung boolean und Zahl hat das Problem des teilweisen Nichtschreibens verursacht. Ich hatte ja auch das Problem, den Datensatz mit dem bool und Zahl Mix zu löschen. Erst am nächsten Tag ließ er sich löschen Den Löschbefehl hatte ich mit dem Editor in eine Datei geschrieben. Fehler ausgeschlossen. Nach dem Löschen des Datensatzes trat kein Fehler mehr auf. Ich bedanke mich für eure Nervenstärke. Sich aus der Ferne da reinzudenken ist nicht einfach. Unzureichende Info meinerseits waren auch nicht hilfreich.
  • Fragen und Hilfe zur externen SQL Datenbank

    1 7
    1 Themen
    7 Beiträge
    fuzzy1955F
    Teil 7: Verwenden der SQL-Daten in Diagrammen bzw. im VIS-2 Reserve! Bitte hier nichts antworten! Thread ist noch in der Entstehung und nur zum Lesen!
  • 270 Themen
    5k Beiträge
    haselchenH
    @Wolfgang-Klein Sorry, aber das kaue ich Dir jetzt nicht auch noch vor. Bemühe doch bitte selbst mal die Suche. Hab ich aus Neugier gemacht und in 2sek zig Lösungen/PINOuts/Schaltpläne gefunden.
  • 184 5k
    184 Themen
    5k Beiträge
    Pedder007P
    Aktuell läuft nur auch mein WoMo Projekt parallel, da gibt es jede Menge properitären Blödsinn der in den ioBroker eingebunden werden will ;-) Habe die letzten zwei 'Tage' damit verbracht mit Hilfe von Gemini einen Gasflaschensensor per Bluetooth in IOB einzubinden, war echt zäh aber nun läufts. Ich habe mir zu 'Agent-DVR' aber mal einen leeren Container mit entsprechendem Namen angelegt, dann vergesse ich es nicht ;-)
  • Fragen zu Docker-Installationen

    20 245
    20 Themen
    245 Beiträge
    Q
    @steff2108 Ich habe ein ähnliches Setup wie du. iobroker läuft bei mir im Docker Container (macvlan) auf meiner DS1821+. Als Backup System habe ich eine DS423+ am Laufen. Meine komplette Docker Umgebung habe ich per Portainer Stacks (Compose) eingerichtet. Die persistenten Container Daten repliziere ich einmal täglich per Synology Snapshot Replication auf die DS423+ Sollte meine primäre DS1821+ ausfallen, brauche ich auf der DS423+ nur die Container zu starten und es läuft wieder alles... Beste Grüße
  • 35 418
    35 Themen
    418 Beiträge
    wendy2702W
    @haselchen : hast du zufällig noch Homeassistant laufen? Wenn ja installiere die Solarman integration, läuft lokal mit dem Dongel
  • [gelöst]Fullybrowser und Aio Neo

    10
    0 Stimmen
    10 Beiträge
    493 Aufrufe
    D
    @ilovegym said in Fullybrowser und Aio Neo: Dank nochmals! @dirkheider Danke, freut mich, dass ich in der Richtung helfen konnte. Das Zeug im Hintergrund frisst mehr, als man in den Einstellungen sehen kann, ich habe meine ganzen Tablets zu 98% fuers Internet gesperrt, und alles deaktiviert/geloescht, was nicht wirklich drauf sein muss. Je neuer das Android, desto schlimmer wird das.. am liebsten sind mir alte mit Android 7, fuer Fullykiosk um ne View anzuzeigen, vollkommen ausreichend.
  • AgentDVR (iSPY)

    Verschoben
    68
    1 Stimmen
    68 Beiträge
    10k Aufrufe
    David G.D
    @segway Auch wenn es grad nicht direkt hilft. Der Dev ist auf Reddit sehr aktiv und antwortet auch immer recht schnell. Hab da schon ein paar Dinge gefragt.
  • ffmpeg: Interessanter Artikel für IP-Kameranutzer ....

    1
    0 Stimmen
    1 Beiträge
    165 Aufrufe
    Niemand hat geantwortet
  • IOBroker Usertreffen Fahrgemeinschaften

    6
    3 Stimmen
    6 Beiträge
    750 Aufrufe
    wauzziW
    Biete Mitfahrgelegenheit von Ludwigsburg (bei Stuttgart) zum IoB Treffen. Bei Interesse gerne via PN melden
  • Frigate und/oder AgentDVR Personen/Kennzeichen Erkennung

    Verschoben frigate agent dvr
    8
    0 Stimmen
    8 Beiträge
    2k Aufrufe
    wendy2702W
    @martinp Gedanke war erstmal die Kennzeichenerkennung in Verbindung mit anderen Triggern zum Garagentor öffnen zu verwenden. Eine Haustüröffnung ist nicht geplant, glaube da würde ich mich nicht drauf verlassen wollen. Allerdings würde ich gerne ein gezielte Nachricht bekommen wenn z.B. meine Kinder unser Haus besuchen wenn wir z.B. nicht zu Hause sind oder eben jemand fremdes.
  • Aufnahmen von IP Kamera auf TrueNAS

    10
    0 Stimmen
    10 Beiträge
    1k Aufrufe
    S
    @martinp sagte in Aufnahmen von IP Kamera auf TrueNAS: @saeft_2003 in den Reolink Kameras kann man doch direkt einen Netzwerkspeicherort hinterlegen [image: 1730550921644-fb1bdad1-8473-4f56-9aa2-159e99feeac3-grafik.png] Ok guter Tipp muss ich mir mal anschauen
  • Nodered Modbus Palette installieren -> Fehler

    Verschoben
    27
    0 Stimmen
    27 Beiträge
    1k Aufrufe
    G
    Danke für eure Hilfe Ich habe jetzt alles neu geflasht auf BookWorm und alles läuft. Danke
  • Leistung des Wechselrichters mit openDTU anpassen

    Verschoben
    22
    0 Stimmen
    22 Beiträge
    1k Aufrufe
    M
    @codierknecht Ich habe die matt-Instanz gestoppt. Wenn ich in der openDTU den Wert ändere dann wird der Wert in innen iobroker geschrieben (hier: 1950W). Möchte ich aber im iobroker den Wert auf 800W ändern dann erfolgt keine Übertragung in die openDTU-Einheit bzw. Wechselrichter) [image: 1730213203664-img_0118-resized.jpeg]
  • Upgrade von Debian 11/Bullseye auf 12/Bookworm

    upgrade bullseye bookworm
    351
    30 Stimmen
    351 Beiträge
    96k Aufrufe
    Pedder007P
    @thomas-braun grundsätzlich hast Du Recht, aber das soll dann der Junior entscheiden/machen ;-)
  • Anzeige ob Auto passend steht

    33
    0 Stimmen
    33 Beiträge
    4k Aufrufe
    Albert KA
    @markus-7 LOL..für mich stimmt das schon :blush:
  • Erweiterung der Anlage von 1p auf 3p - passt das?

    Verschoben
    2
    1
    0 Stimmen
    2 Beiträge
    295 Aufrufe
    HomoranH
    @stefan-falt sagte in Erweiterung der Anlage von 1p auf 3p - passt das?: Reicht es wenn ich mit 50mm² verkable? Victron schreibt 70 mm² vor
  • UniFi Network Application 8.3.x -> NAT deaktivieren

    unifi ubiquiti nat
    10
    0 Stimmen
    10 Beiträge
    2k Aufrufe
    Samson71S
    @ilovegym "etwas" übertrieben trifft es vermutlich :grinning: [image: 1729933859153-37232481-e5a7-491e-91f6-5c6a6ed7187c-image.png]
  • Erfahrungen zu tibber und Hardware-Voraussetzungen

    16
    0 Stimmen
    16 Beiträge
    2k Aufrufe
    HomoranH
    @xxjooo sagte in Erfahrungen zu tibber und Hardware-Voraussetzungen: Wir sind mit einem Haus mit 4 Leuten in der Mitte zwischen K und BN immer bei deutlich über 5.000kWh/Jahr. nicht weit davon etwas nördlich Mit unseren beiden Töchtern lagen wir damals bei 14.000kWh/anno. Warmwasser und Kochen über Strom. und geduscht wurde bis die Sicherung ausstieg. (ok, diverse große Warmwasseraquarien, ein Blechpool und ein HomeOffice waren auch noch dabei.) inzwischen lagen wir bei etwa 5.000, als dann die Stromppreise 2022 stiegen, nochmal radikal gesenkt auf etwa 3500netto. Netto deswegen, weil dann die Wärmepumpe und das eAuto kamen. liegen jetzt wieder zwischen 6000 und 6500 Verbrauch und dank Solar und Batterie bei irgendwas um 3500 Bezug
  • zigbee2MQTT server + Lidl Fluter HG08010 (Geräte Bug?)

    4
    1
    0 Stimmen
    4 Beiträge
    209 Aufrufe
    MartinPM
    @arteck Sie melden sich ja ... nur, wenn man sie nicht lange genug vom Netz trennt mit dem falschen Zustand ... Ist eben Discounterware ;-) Jetzt noch mal das Logging mit nur kurzem simulierten Netzausfall (Schalte vorher kurz An und wieder Aus) 2024-10-23 14:33:32z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Lidl Fluter', payload '{"brightness":254,"color":{"x":0.3131,"y":0.3232},"color_mode":"color_temp","color_power_on_behavior":"initial","color_temp":153,"last_seen":"2024-10-23T14:33:32+02:00","linkquality":184,"state":"OFF"}' info 2024-10-23 14:33:32z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Lidl Fluter', payload '{"brightness":254,"color":{"x":0.3131,"y":0.3232},"color_mode":"color_temp","color_power_on_behavior":"initial","color_temp":153,"last_seen":"2024-10-23T14:33:32+02:00","linkquality":184,"state":"ON"}' info 2024-10-23 14:33:33z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Lidl Fluter', payload '{"brightness":254,"color":{"x":0.3131,"y":0.3232},"color_mode":"color_temp","color_power_on_behavior":"initial","color_temp":153,"last_seen":"2024-10-23T14:33:33+02:00","linkquality":183,"state":"ON"}' info 2024-10-23 14:33:33z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Lidl Fluter', payload '{"brightness":254,"color":{"x":0.3131,"y":0.3232},"color_mode":"color_temp","color_power_on_behavior":"initial","color_temp":153,"last_seen":"2024-10-23T14:33:33+02:00","linkquality":183,"state":"OFF"}' info 2024-10-23 14:33:54z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Lidl Fluter', payload '{"brightness":254,"color":{"x":0.3131,"y":0.3232},"color_mode":"color_temp","color_power_on_behavior":"initial","color_temp":153,"last_seen":"2024-10-23T14:33:54+02:00","linkquality":171,"state":"OFF"}' Die Lampe ist "ON" (!), aber state wird nach "Besaften" mit "OFF" (!) gemeldet ... Ändert sich auf in den ersten 2 Minuten nach dem Einschalten der Netzversorgung der Lampe nicht ... Es gibt also eine Meldung beim Einschalten, die ist aber falsch...
  • komme nicht mehr in den Unifi-Controller

    20
    0 Stimmen
    20 Beiträge
    909 Aufrufe
    NegaleinN
    @meister-mopper sagte in komme nicht mehr in den Unifi-Controller: Schau doch mal nach, ob man es von der cli anschieben kann. gefunden: (https://community.ui.com/questions/UniFi-How-do-I-reset-the-UAP-to-factory-default-settings/39013761-714c-4e1a-a428-aa56e1b99f40) :)
  • Bekomme mount nicht in fsfab

    7
    0 Stimmen
    7 Beiträge
    329 Aufrufe
    CodierknechtC
    @david-g Habe auch lange daran rumgedoktert und bin zu folgender Lösung gekommen: //192.168.178.5/Docker /mnt/nas cifs x-systemd.automount,x-systemd.requires=network-online.target,file_mode=0666,dir_mode=0777,credentials=/etc/smbcredentials 0 0
  • COMET DECT Thermostat retten

    13
    1
    0 Stimmen
    13 Beiträge
    1k Aufrufe
    BananaJoeB
    @martinp sagte in COMET DECT Thermostat retten: @bananajoe Da muss man aufpassen, dass man die Dämmung mit einer Sperrbahn gegen den Raum abdichtet, sonst kriecht die Feuchtigkeit in die Dämmung und kondensiert dann durch das Wärmegefälle nach außen am Taupunkt ... öhm, jupp. Folie/Dampfsperre ist da auch hinter
  • Shelly BLU USB Gateway als Beacon? suche USB Beacon

    4
    0 Stimmen
    4 Beiträge
    365 Aufrufe
    D
    @schmello said in Shelly BLU USB Gateway als Beacon? suche USB Beacon: @dieter_p Muss ich in der App vom Feasycom Stick noch etwas Einstellen? Aktuell läuft soweit ich weiß die feasycom app nicht auf meinem Pixel mit Android 14 bzw. hab schon was länger nicht mehr versucht, von daher alles ausm Gedächtnis. Läuft aber hab keinen Beacon am Mann zum testen. Ich glaube, "irgendwas" war in den beacons die ich gekauft hab bereits konfiguriert und ob das in deinem Stick genauso ist, nicht zu sagen. In jeden Fall würde ich es prüfen, aus Sicherheitsgründen und auch weil es Sinn macht und du dort Sendeintervalle etc ganz genau einstellen kannst. Ebenso unterstützen die Beacons von feasycom verschiedene Typen (ibeacon, Eddystone etc etc.) die dort angelegt werden können. Ungenutztes würde ich sowieso löschen. Ich verwende derzeit noch ESPHome und hab noch nicht Tasmota mit BLE Scanner in Betrieb genommen. Prinzipell das Ganze über iBeacon konfiguriert und ich prüfe mit dem Scanner auf die MAC-Adresse des Beacon. Ablesbar auch mit der feasycom app wenn ein iBeacon konfiguriert ist. Unter Tasmota sehe ich keinen Grund warum es nicht dort genauso gehen sollte. Ein Eindruck zur App, kannst Du hier bekommen: https://www.youtube.com/watch?v=4r0E7_mBHVQ
  • Wie mittels LUXTRONIK-Adapter Wassertemperatur einstellen?

    5
    3
    0 Stimmen
    5 Beiträge
    598 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
    864 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.

716

Online

32.6k

Benutzer

82.2k

Themen

1.3m

Beiträge