Skip to content

JavaScript

2.5k Topics 49.7k Posts

Hilfe für Skripterstellung mit JavaScript

NEWS

  • JSON Liste sortieren (Funktion)

    62
    4
    0 Votes
    62 Posts
    11k Views
    M
    @djmarc75 ja es landet auch alles sortiert im Datenpunkt. vielen dank noch mal.
  • [gelöst]Enum während Laufzeit ändern

    2
    0 Votes
    2 Posts
    152 Views
    paul53P
    @ben1983 sagte: Id aus „Weihnachtsbeleuchtung“ heraus zu nehmen und wo anders mit rein? Versuche es mal so: const idEnum1 = 'enum.functions.weihnachtsbeleuchtng'; const idEnum2 = 'enum.functions.anderes_Gewerk'; const idDP = 'xyz'; // Steckdose const obj1 = getObject(idEnum1); const obj2 = getObject(idEnum2); var idx = obj1.common.members.indexOf(idDP); if(idx > -1) { obj1.common.members.splice(idx, 1); // entfernen obj2.common.members.push(idDP); // hinzufügen } else { idx = obj2.common.members.indexOf(idDP); if(idx > -1) { obj2.common.members.splice(idx, 1); // entfernen obj1.common.members.push(idDP); // hinzufügen } } if(idx > -1) { setObject(idEnum1, obj1); setObject(idEnum2, obj2); }
  • Logging ohne Scripname in der Nachricht

    javascript
    6
    0 Votes
    6 Posts
    682 Views
    F
    @bourton88 sagte in Logging ohne Scripname in der Nachricht: Kann das jemand erklären? richtige Fehler sind nur die welche im Log zur Laufzeit auftauchen. Die roten Kringel sind 'nur' Hinweise und oft fehlerhaft.
  • "Gesunde" Anzahl von registrierten Triggern

    20
    0 Votes
    20 Posts
    724 Views
    haus-automatisierungH
    @paul53 Ja, aber nicht alle. Rolle geht z.B. nicht.
  • sourcesanalytix per JS aktivieren

    7
    0 Votes
    7 Posts
    289 Views
    bahnuhrB
    Hat sich erledigt. Hab mir ein Script geschrieben.
  • Abruf von JSON vom Truckstick

    4
    0 Votes
    4 Posts
    658 Views
    CodierknechtC
    @robbsen Deine lokalen IP's musst Du nicht X'en. Die sehen bei allen gleich aus. @robbsen sagte in Abruf von JSON vom Truckstick: Leider habe ich sonst immer Blockly genutzt und das ist hier vermutlich fehl am Platz. Geht mit Blockly genau so gut. Wie sieht denn das JSON aus?
  • getState - außerhalb einer Funktion

    3
    3
    0 Votes
    3 Posts
    212 Views
    N
    @paul53 DANKE, für diesen schei... Haken habe ich einen Tag am Kopf gekratzt. Danke für den Hinweis, dass bei späteren Problemen eher der Text als Bilder helfen.
  • (gelöst) SQL Abfrage als Function in einem javascript

    Moved
    2
    0 Votes
    2 Posts
    394 Views
    Norwegen60N
    OK, ich habe es selbst herausbekommen. Die Hürden waren nicht genau zu wissen, wie bei JavaScript function und deren Parameter funktionieren die Erkenntnis, dass bei SQL die Ergebnisse zeitverzögert zurück kommen. Wenn man in der Function das Ergebnis als result zurück gegeben hat, hat der Wert im Log nie gestimmt. Die Suche warum die Werte nie gestimmt haben, hat einiges an Zeit verschlungen Ich habe es deshalb wie folgt realisiert. Der Einfacheit halber verwende ich die Funktion um Jahresergebnisse zu liefern. Da muss nicht Jahr/Monat verschlüsselt werden (Monatsabfrage steht ja schon im vorigen Post) function GetEnergyYear(ID, Year, DataPoint, DataPointCurrent = '') { let ValueCurrent = 0; let sSQL1 = 'use ioBroker DECLARE @ID int = ' +String(ID) +', @Year int ='+String(Year); let sSQL2 = 'select max(val) from ts_number where ((id = @ID) and (year(DATEADD(s, ts/1000, \'1970-01-01\')) = year(getdate())-@Year-1)) or (id = 0)'; let sSQL =sSQL1 + ' select max(val) -(' + sSQL2 +') from ts_number where ((id = @ID) and (year(DATEADD(s, ts/1000, \'1970-01-01\')) = year(getdate())-@Year)) or (id = 0)'; sendTo('sql.0', 'query', sSQL, async (result) =>{ setState(DataPoint , getAttr((getAttr(result, 'result')[0]), ''), true); }); // Wenn Korrekturwert (aktueller Tages-Wert) mit übergeben wurde, diesen zum Wert addieren // Hier muss man wissen, dass immer nur der Endwert eines jeden Tages abliegt. // Der Stand des aktuellen Tages fehlt also. Der kann per DataPointCurrent übergeben und hinzuaddiert werden if (String(DataPointCurrent) != '') { ValueCurrent = getState(DataPointCurrent).val; if (Logging) {console.log('###2: ValueCurrent = ' + String(ValueCurrent))}; setState(DataPoint /* rEnergyRateDay */, (getState(DataPoint).val + ValueCurrent), true); }; if (Logging) {console.log('###2: '+ String(DataPoint) + ' = ' + String(getState(DataPoint).val))}; } // ############################################################################################################################# // alle 2 Minute aktuelle Monatsverbräuche berechnen schedule('{"time":{"start":"00:00","end":"24:00","interval":2,"mode":"minutes"},"period":{"days":1}}', async () => { console.log(('### Verbrauch aktueller Monat ###')); // Und so erfolgt die Abfrage. 88 und 100 sind die Datapoint ID des Tagesendwertes GetEnergyYear(88,0,'0_userdata.0.PV.rPV_Energy_RateYear','0_userdata.0.PV.rPV_Energy_Day'); GetEnergyYear(88,1,'0_userdata.0.PV.rPV_Energy_RateYearBefore'); // der benötigt keine Korrektur da ja alle Tage abgelegt sind GetEnergyYear(100,0,'0_userdata.0.PV.rUsed_Energy_RateYear','0_userdata.0.PV.rUsed_Energy_Day'); GetEnergyYear(100,1,'0_userdata.0.PV.rUsed_Energy_RateYearBefore'); }); Kann sein, dass es einfacher geht, aber so funktioniert es Grüße Gerd
  • HTML-Tabelle für Time-Switch Adapter

    javascript
    49
    2
    5 Votes
    49 Posts
    8k Views
    liv-in-skyL
    @buchner51 sorry - muss ich sehen - mir fällt im moment nix ein
  • Typescript setObejct kompelier fehler

    13
    1
    0 Votes
    13 Posts
    1k Views
    I
    Ich muss das Thema leider noch mal hochholen. Meine Test Version funktioniert ja. const testPath = "0_userdata.0.dev.color_mode" const obj= getObject(testPath) as iobJS.StateObject; Als ich das ganze aber dynamisch machen wollte z.b. async function updateEnum(path:string, states, statesLength){ const obj= getObject(path) as iobJS.StateObject; hatte ich wieder den Fehler. Wenn ich aus dem const ein var machen geht es auch nicht mehr var testPath = "0_userdata.0.dev.color_mode" const obj= getObject(testPath) as iobJS.StateObject; und es reicht nicht aus den string in ein const zu packen async function updateEnum(path:string, states, statesLength){ const testPath = path const obj= getObject(testPath) as iobJS.StateObject; immer bekommen ich script.js.common.dev: TypeScript compilation failed: const obj = getObject(path) as iobJS.StateObject; ^ERROR: Conversion of type '{ type: "meta" | "config" | "user" | "state" | "instance" | "adapter" | "channel" | "folder" | "device" | "script" | "enum" | "group" | "host" | "chart"; ts: number; from: string; common: { ...; }; ... 8 more ...; encryptedNative: string[]; }' to type 'StateObject' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Types of property 'common' are incompatible. Type '{ [x: string]: any; [x: number]: any; }' is missing the following properties from type 'StateCommon': read, write, role, name Leider fehlt mir da echt tiefergehendes Javascript/typescript wissen um das zu verstehen. Würde mir noch mal jemand auf die Sprünge helfen?
  • IP Devices im Netzwerk - HTML Tabelle vis, Iqontrol

    javascript template
    493
    3
    9 Votes
    493 Posts
    129k Views
    O
    @liv-in-sky Super, danke dir
  • [gelöst] Ersetzen eines json Array elements

    22
    0 Votes
    22 Posts
    1k Views
    Ben1983B
    @ticaki OK, da bin ich ja beruhigt. Hier mein Komplettes Skript zum Zuweisen: // Id Deklaration der States (für spätere Abrufe) const idOffeneTueren = "0_userdata.0.Produktiv.Tueren.Innen.offeneTueren"; const idGeschlosseneTueren = "0_userdata.0.Produktiv.Tueren.Innen.geschlosseneTueren"; const idTueren = "0_userdata.0.Produktiv.Tueren.Innen.tueren"; // Türobjekte definieren let tueren = {}; let offeneTueren = {}; let geschlosseneTueren = {}; //Arrays bei Skriptstart anlegen $(`state(${enumtypeFunctions}=${enumTuerInnen})`).each((id)=>{ //objekt und state holen let obj = getObject(id); let state = getState(id); // Objekte zuweisen assignObject(obj,state); // Arrays beschreiben setState(idTueren,JSON.stringify(Object.values(tueren)),true); setState(idOffeneTueren,JSON.stringify(Object.values(offeneTueren)),true); setState(idGeschlosseneTueren,JSON.stringify(Object.values(geschlosseneTueren)),true); }); // Objekte zuweisen function assignObject(obj,state){ // Zuweisen des allgemeinen Türobjekts tueren[obj._id] = {name:obj.common.name, zustand: state.val?"geschlossen": "offen"}; // Zuweisen des Objekts für die offenen oder geschlossenen Türen if(state.val){ geschlosseneTueren[obj._id] = tueren[obj._id]; delete offeneTueren[obj._id]; } else { offeneTueren[obj._id] = tueren[obj._id]; delete geschlosseneTueren[obj._id]; } } /********************************************************************************************************* * *********************************** Ab hier bei Änderungen ******************************************** ******************************************************************************************************* */ // Abfrage, ob sich ein Türzustand geändert hat $(`state(${enumtypeFunctions}=${enumTuerInnen})`).on((dp)=>{ // Objekt holen und zuweisen let obj = getObject(dp.id); assignObject(obj,dp.state); // Arrays beschreiben setState(idTueren,JSON.stringify(Object.values(tueren)),true); setState(idOffeneTueren,JSON.stringify(Object.values(offeneTueren)),true); setState(idGeschlosseneTueren,JSON.stringify(Object.values(geschlosseneTueren)),true); });
  • Script fürTabelle der Batterie Zustände

    javascript monitoring template
    1k
    27
    15 Votes
    1k Posts
    609k Views
    hg6806H
    An alle die Probleme mit der Aktualisierung der Homematic Fensterkontakte haben, hier der Workaround. Danke an @liv-in-sky für die Unterstützung. Problem, zumindest bei mir, ist, dass die Fensterkontakte 2x "LowBat" Datenpunkte haben. 1x unter xxxx.0 und 1x unter xxxx.1 Das Script schaut aber normalerweise unter : $('hm-rpc.*.0.LOWBAT').each(function(id,....... Der LowBat Wert wird aber unter xxxx.1 aktualisiert. Wenn man jetzt die Zeile auf $('hm-rpc.*.1.LOWBAT').each(function(id...... ändert funktionieren allerdings die anderen nicht mehr. Also muss man auf $('hm-rpc...*.LOWBAT').each(function(id,...... setzen und die Fensterkontakte, die nun doppelt aufgeführt filtern unter: var filterArray=["hm-rpc.0.NEQ0xxxxx.0.LOWBAT","hm-rpc.0.NEQ06xxxxx.0.L.......... rausfiltern. Also die Nuller. Seltsamerweise hatte es ja mal ursprünglich funktioniert. Ich weiß jetzt nicht wo was geändert wurde. In der Zentrale CCU.x oder im HM.RPC Adapter.
  • Aufrufende Webseite ermitteln

    1
    0 Votes
    1 Posts
    180 Views
    No one has replied
  • Pullen mehrerer DP aus history via Javascript

    7
    0 Votes
    7 Posts
    502 Views
    jmeister79J
    @haus-automatisierung ja das ist natürlich sehr viel eleganter. danke dir. Ich hab dieses Prinzip damals aus unwissenheit begonnen und das nun überall so, ist natürlich auch mal zeit das aufzuräumen.
  • Gültigkeitsbereich Variablen

    8
    0 Votes
    8 Posts
    662 Views
    haus-automatisierungH
    @spider_01 Du musst sendToAsync nutzen. Nicht mehr sendTo. Nur die erste liefert ein Promise zurück. sendTo arbeitet ja mit Callback.
  • Datenpunkt überschreiben

    2
    0 Votes
    2 Posts
    272 Views
    O
    @woostel ich bin jetzt nicht der große Experte was programmieren angeht, aber wie ich das sehe, holst du dir in der Zeile 17 das mit Daten befüllte JSON in eine Variable und pusht danach in deiner "getData Funktion" drauf.
  • Aternative Methode für getObjectList

    7
    0 Votes
    7 Posts
    752 Views
    paul53P
    @flying-bolt const ids = $('hm-rpc.0.0000*'); ids.each(function(id) { log(id); });
  • Cannot find module 'googleapis' / Authentifizierungsproblem

    5
    0 Votes
    5 Posts
    507 Views
    M
    @codierknecht das hat schonmal geholfen. Danke dafür. Zum Laufen bekomme ich den Code aber leider noch nicht. Ich will einmal wöchentlich die Bilder einer gesamten Woche bei Google Fotos von vor 1226 Tagen in ein Album taggen. // Zugriff auf Google Fotos API const {google} = require('googleapis'); const Photos = require('googlephotos'); const CronJob = require('cron').CronJob; // Authentifizierung mit OAuth 2.0 const OAuth2 = google.auth.OAuth2; const oauth2Client = new OAuth2(); oauth2Client.setCredentials({ access_token: '', refresh_token: '', client_id: '', client_secret: '', }); // Funktion zum Prüfen der OAuth2-Autorisierung async function checkAuthorization() { try { // Access Token prüfen if (!oauth2Client.credentials || !oauth2Client.credentials.access_token) { console.error('Kein Access Token vorhanden. Autorisierung fehlgeschlagen.'); return false; } // Gültigkeit des Access Tokens prüfen const expiryDate = new Date(oauth2Client.credentials.expiry_date); if (expiryDate < new Date()) { console.error('Access Token abgelaufen. Autorisierung fehlgeschlagen.'); return false; } console.info('OAuth2-Autorisierung erfolgreich!'); return true; } catch (error) { console.error(`Autorisierungsfehler: ${error.message}`); return false; } } // Aktuelles Datum const today = new Date(); const todayStr = today.toLocaleDateString('de-DE'); // Albumname für die Bilder der Woche const albumName = `Woche vom ${todayStr}`; // Funktion zum Abrufen der Fotos von vor 1226 Tagen async function getPhotosFrom1226DaysAgo() { const startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1226); const endDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + 7); try { const response = await Photos.mediaItems.list({ auth: oauth2Client, searchQuery: `date >= '${startDate.toISOString()}' AND date <= '${endDate.toISOString()}'`, pageSize: 100, // Anzahl der Fotos pro Seite }); // Extrahieren der Foto-IDs aus der Antwort const photoIds = response.data.mediaItems.map(item => item.id); return photoIds; } catch (error) { console.error(`Fehler beim Abrufen von Fotos: ${error.message}`); return []; // Leere Liste zurückgeben, falls Fehler auftreten } } // Funktion zum Erstellen eines neuen Albums async function createAlbum(albumName) { const createAlbumRequest = { album: { title: albumName, }, }; const response = await Photos.albums.create(createAlbumRequest); return response.data.id; } // Funktion zum Taggen der Fotos mit dem neuen Album async function tagPhotosWithAlbum(albumId, photoIds) { const tagPhotosRequest = { albumId: albumId, newMediaItemIds: photoIds, }; await Photos.mediaItems.batchAddMediaItemsToAlbum(tagPhotosRequest); } // Hauptfunktion async function main() { // Prüfung der OAuth2-Autorisierung const isAuthorized = await checkAuthorization // Fotos von vor 1226 Tagen abrufen const photos = await getPhotosFrom1226DaysAgo(); // Neues Album erstellen const albumId = await createAlbum(albumName); // Fotos mit dem neuen Album taggen await tagPhotosWithAlbum(albumId, photos.map((photo) => photo.id)); console.info('Die Bilder der Woche wurden erfolgreich in das neue Album ' + albumName + ' getaggt.'); } // Cron-Job-Zeitsteuerung const cronJob = new CronJob('05 21 * * *', async function() { await main(); }); // Starten des Cron-Jobs cronJob.start(); Die Credentials sind dabei natürlich gepflegt. Raus kommt dabei 21:28:00.018 error javascript.0 (831843) script.js.Dev.Google_Fotos: Fehler beim Abrufen von Fotos: Cannot read properties of undefined (reading 'list') 21:28:00.021 error javascript.0 (831843) script.js.Dev.Google_Fotos: TypeError: Cannot read properties of undefined (reading 'create') 21:28:00.021 error javascript.0 (831843) at createAlbum (script.js.Dev.Google_Fotos:54:40) 21:28:00.021 error javascript.0 (831843) at main (script.js.Dev.Google_Fotos:75:25) 21:28:00.023 error javascript.0 (831843) at CronJob.<anonymous> (script.js.Dev.Google_Fotos:86:3) Also ich glaube die Authentifizierung klappt nicht. Ich sehe auch keinen Traffic in der Google Cloud. Vielleicht weil ich keine Authorisierte JS Quelle angegeben habe? [image: 1709670470214-00c645db-5618-47f6-a017-e321dd74f9f2-image.png] Aber mein iobroker hängt nicht öffentlich im Netz und hat keine Portfreigabe (hoffe ich). Hab da keine URL
  • [gelöst] Datum von Gestern ermitteln

    13
    0 Votes
    13 Posts
    1k Views
    mickymM
    @michihorn Gibt meines Erachtens keinen, Die Bibliothek heißt moment.js auch, so wie man node.js sagt, aber moment und node meint. Das js kommt einfach von Javascript. https://momentjs.com/docs/#/use-it/ [image: 1709585094759-4fd84c43-023b-4f6f-bd92-1a83a3444daf-image.png] [image: 1709585141166-98921c5f-cac6-4fe3-9bc2-90423cabe8de-image.png] Insofern gibts da keinen Unterschied und meint dieselbe Bibliothek.

266

Online

33.0k

Users

83.4k

Topics

1.3m

Posts