From a2feae891e9785c82b7d4d50bf9cf255d55d7e5c Mon Sep 17 00:00:00 2001 From: Thomas <101348966+tt-tom17@users.noreply.github.com> Date: Fri, 26 Jan 2024 18:50:47 +0100 Subject: [PATCH] Script vom Wiki nach Github schieben --- ioBroker/Blockly/Abfallkalender.js | 74 -------- ioBroker/Blockly/Abfallkalender.ts | 224 +++++++++++++++++++++++++ ioBroker/Blockly/CardChart_History.js | 50 ++++++ ioBroker/Blockly/CardLChart_History.js | 78 +++++++++ ioBroker/Blockly/CardPower.js | 54 ++++++ ioBroker/Blockly/CradLChart_Influx2.js | 109 ++++++++++++ 6 files changed, 515 insertions(+), 74 deletions(-) delete mode 100644 ioBroker/Blockly/Abfallkalender.js create mode 100644 ioBroker/Blockly/Abfallkalender.ts create mode 100644 ioBroker/Blockly/CardChart_History.js create mode 100644 ioBroker/Blockly/CardLChart_History.js create mode 100644 ioBroker/Blockly/CardPower.js create mode 100644 ioBroker/Blockly/CradLChart_Influx2.js diff --git a/ioBroker/Blockly/Abfallkalender.js b/ioBroker/Blockly/Abfallkalender.js deleted file mode 100644 index 71255bb9..00000000 --- a/ioBroker/Blockly/Abfallkalender.js +++ /dev/null @@ -1,74 +0,0 @@ -const idAbfalliCal = 'ical.1'; // iCal Instanz zum Abfallkalender -const idZeichenLoeschen = 14; // x Zeichen links vom String abziehen, wenn vor dem Eventname noch Text steht z.B. Strassenname; Standard = 0 -const idRestmuellName ='Hausmüll'; // Schwarze Tonne -const idWertstoffName = 'Gelber Sack'; // Gelbe Tonne / Sack -const idPappePapierName = 'Papier'; // Blaue Tonne -const idBioabfaelleName = 'Biomüll'; // Braune Tonne - - -var i, Muell_JSON, Event2, Color = 0; - -for (i = 1; i <= 4; i++) { - if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.date')) { - log(i + '.date nicht vorhanden, wurde erstellt'); - createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.date', '', - { - name: parseFloat(i) + '.date', - role: 'state', - type: 'string', - read: true, - write: true, - def: '' - }); - }; - if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.event')) { - log(i + '.event nicht vorhanden, wurde erstellt'); - createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.event', '', - { - name: parseFloat(i) + '.event', - role: 'state', - type: 'string', - read: true, - write: true, - def: '' - }); - }; - if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.color')) { - log(i + '.color nicht vorhanden, wurde erstellt'); - createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.color', 0, - { - name: parseFloat(i) + '.color', - role: 'state', - type: 'number', - read: true, - write: true, - def: 0 - }); - }; -} - -function subsequenceFromStartLast(sequence, at1) { - var start = at1; - var end = sequence.length; - return sequence.slice(start, end); -} - -on({ id: idAbfalliCal + '.data.table', change: "ne" }, async function () { - - for (i = 0; i <= 3; i++) { - Muell_JSON = getState(idAbfalliCal + '.data.table').val; - setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.date'].join('')), getAttr(Muell_JSON, (String(i) + '.date')), false, parseInt(((0) || "").toString(), 10), false); - Event2 = subsequenceFromStartLast(getAttr(Muell_JSON, (String(i) + '.event')), idZeichenLoeschen); - setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.event'].join('')), Event2, false, parseInt(((0) || "").toString(), 10), false); - if (Event2 == idRestmuellName) { - Color = 33840; - } else if (Event2 == idBioabfaelleName) { - Color = 2016; - } else if (Event2 == idPappePapierName) { - Color = 31; - } else if (Event2 == idWertstoffName) { - Color = 65504; - } - setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.color'].join('')), Color, false, parseInt(((0) || "").toString(), 10), false); - } -}); diff --git a/ioBroker/Blockly/Abfallkalender.ts b/ioBroker/Blockly/Abfallkalender.ts new file mode 100644 index 00000000..9419574d --- /dev/null +++ b/ioBroker/Blockly/Abfallkalender.ts @@ -0,0 +1,224 @@ +/* + * @author 2023 @tt-tom + * + * Version 5.1.1 + * + * Das Script erstellt die Datenpunkte und Alias für den Abfallkalender im Sonoff NSPanel + * Es wird der iCal Adapter benötigt und eine URL mit Terminen vom Entsorger bzw. eine .ics-Datei mit den Terminen. + * Das Script triggert auf dem bereitgestellten JSON im iCal adapter und füllt die 0_userdata.0 Datenpunkte + * Weitere Informationen findest du in der FAQ auf Github https://github.com/joBr99/nspanel-lovelace-ui/wiki + * + * changelog + * - 06.12.2023 - v5.0.2 add custom name for trashtype + * - 06.12.2023 - v5.1.0 Refactoring + * - 22.01.2024 - v5.1.1 Add tow Events more + * + * +*/ + + +const idTrashData: string = 'ical.0.data.table'; // Datenpunkt mit Daten im JSON Format +const idUserdataAbfallVerzeichnis: string = '0_userdata.0.Abfallkalender'; // Name des Datenpunktverzeichnis unter 0_userdata.0 -> Strandard = 0_userdata.0.Abfallkalender +const idAliasPanelVerzeichnis: string = 'alias.0.NSPanel.allgemein'; //Name PanelVerzeichnis unter alias.0. Standard = alias.0.NSPanel.1 +const idAliasAbfallVerzeichnis: string = 'Abfall'; //Name Verzeichnis unterhalb der idPanelverzeichnis Standard = Abfall + +const anzahlZeichenLoeschen: number = 14; // x Zeichen links vom String abziehen, wenn vor dem Eventname noch Text steht z.B. Strassenname; Standard = 0 +const jsonEventName1: string = 'Hausmüll'; // Vergleichstring für Schwarze Tonne +const customEventName1: string = ''; // benutzerdefinierter Text für schwarze Tonne +const jsonEventName2: string = 'Gelber Sack'; // Vergleichstring für Gelbe Tonne / Sack +const customEventName2: string = ''; // benutzerdefinierter Text für gelbe Tonne +const jsonEventName3: string = 'Papier'; // Vergleichstring für Blaue Tonne +const customEventName3: string = ''; // benutzerdefinierter Text für blaue Tonne +const jsonEventName4: string = 'Biomüll'; // Vergleichstring für Braune Tonne +const customEventName4: string = ''; // benutzerdefinierter Text für braune Tonne +const jsonEventName5: string = 'Treppe'; // Vergleichstring für Event 5 +const customEventName5: string = 'Besen schwingen'; // benutzerdefinierter Text für Event 5 +const jsonEventName6: string = ''; // Vergleichstring für Event 6 +const customEventName6: string = ''; // benutzerdefinierter Text für Event 6 + +const Debug: boolean = false; + +// ------------------------- Trigger zum füllen der 0_userdata Datenpunkte aus dem json vom ical Adapter ------------------------------- + +// Trigger auf JSON Datenpunkt +on({ id: idTrashData, change: 'ne' }, async function () { + JSON_auswerten(); +}); + +// ------------------------------------- Ende Trigger ------------------------------------ + +// ------------------------------------- Funktion JSON auswerten und DP füllen ------------------------------- +async function JSON_auswerten() { + try { + + let trashJSON: any; + let instanzName: any; + let eventName: string; + let eventDatum: string; + let eventStartdatum: string; + let farbNummer: number = 0; + let farbString: string; + let abfallNummer: number = 1; + + trashJSON = getState(idTrashData).val; + instanzName = idTrashData.split('.'); + + if (Debug) log('Rohdaten von Instanz ' + instanzName[0] + ': ' + JSON.stringify(trashJSON), 'info') + + + if (Debug) log('Anzahl Trash - Daten: ' + trashJSON.length, 'info'); + + for (let i = 0; i < trashJSON.length; i++) { + if (abfallNummer === 7) { + if (Debug) log('Alle Abfall-Datenpunkte gefüllt', 'warn'); + break; + } + + log('Daten vom ical Adapter werden ausgewertet', 'info'); + eventName = getAttr(trashJSON, (String(i) + '.event')).slice(anzahlZeichenLoeschen, getAttr(trashJSON, (String(i) + '.event')).length); + // Leerzeichen vorne und hinten löschen + eventName = eventName.trimEnd(); + eventName = eventName.trimStart(); + eventDatum = getAttr(trashJSON, (String(i) + '.date')); + eventStartdatum = getAttr(trashJSON, (String(i) + '._date')); + + let d: Date = currentDate(); + let d1: Date = new Date(eventStartdatum); + + if (Debug) log('--------- Nächster Termin wird geprüft ---------', 'info'); + //if (Debug) log(d + ' ' + d1, 'info'); + if (Debug) log('Startdatum UTC: ' + eventStartdatum, 'info'); + if (Debug) log('Datum: ' + eventDatum, 'info'); + if (Debug) log('Event: ' + eventName, 'info'); + if (Debug) log('Kontrolle Leerzeichen %' + eventName + '%', 'info'); + + if (d.getTime() <= d1.getTime()) { + if ((eventName == jsonEventName1) || (eventName == jsonEventName2) || (eventName == jsonEventName3) || (eventName == jsonEventName4) || (eventName == jsonEventName5) || (eventName == jsonEventName6)) { + + switch (eventName) { + case jsonEventName1: + farbNummer = 33840; + if (customEventName1 != '') { + eventName = customEventName1; + if (Debug) log('Event customName: ' + eventName, 'info'); + }; + break; + case jsonEventName2: + farbNummer = 65504; + if (customEventName2 != '') { + eventName = customEventName2; + if (Debug) log('Event customName: ' + eventName, 'info'); + }; + break; + case jsonEventName3: + farbNummer = 31; + if (customEventName3 != '') { + eventName = customEventName3 + if (Debug) log('Event customName: ' + eventName, 'info'); + }; + break; + case jsonEventName4: + farbNummer = 2016; + if (customEventName4 != '') { + eventName = customEventName4; + if (Debug) log('Event customName: ' + eventName, 'info'); + }; + break; + case jsonEventName5: + farbNummer = 2016; + if (customEventName5 != '') { + eventName = customEventName5; + if (Debug) log('Event customName: ' + eventName, 'info'); + }; + break; + case jsonEventName6: + farbNummer = 2016; + if (customEventName6 != '') { + eventName = customEventName6 + if (Debug) log('Event customName: ' + eventName, 'info'); + }; + break; + } + + //if (farbString != undefined) farbNummer = rgb_dec565(hex_rgb(farbString)); + + + setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.date', eventDatum); + setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.event', eventName); + setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.color', farbNummer); + + + //if (Debug) log('farbString: ' + farbString + ' farbNummer: ' + farbNummer, 'info'); + if (Debug) log('Abfallnummer: ' + abfallNummer, 'info'); + + abfallNummer += 1 + } else { + if (Debug) log('Kein Abfalltermin => Event passt mit keinem Abfallnamen überein.', 'warn'); + } + } else { + if (Debug) log('Termin liegt vor dem heutigen Tag', 'warn'); + } + } + } catch (err) { + log('error at subscrption: ' + err.message, 'warn'); + } +}; + +// ------------------------------------- Ende Funktion JSON ------------------------------ + +// ------------------------------------- Funktion zur Prüfung und Erstellung der Datenpunkte in 0_userdata.0 und alias.0 ----------------------- + +async function Init_Datenpunkte() { + try { + for (let i = 1; i <= 6; i++) { + if (existsObject(idUserdataAbfallVerzeichnis + '.' + String(i)) == false) { + log('Datenpunkt ' + idUserdataAbfallVerzeichnis + '.' + String(i) + ' werden angelegt', 'info') + await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.date', '', { type: 'string' }); + await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.event', '', { type: 'string' }); + await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.color', 0, { type: 'number' }); + setObject(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis, { type: 'device', common: { name: { de: 'Abfall', en: 'Trash' } }, native: {} }); + setObject(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i), { type: 'channel', common: { role: 'warning', name: { de: 'Ereignis ' + String(i), en: 'Event' + String(i) } }, native: {} }); + await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.TITLE', idUserdataAbfallVerzeichnis + '.' + String(i) + '.event', true, { type: 'string', role: 'weather.title.short', name: { de: 'TITEL', en: 'TITLE' } }); + await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.LEVEL', idUserdataAbfallVerzeichnis + '.' + String(i) + '.color', true, { type: 'number', role: 'value.warning', name: { de: 'LEVEL', en: 'LEVEL' } }); + await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.INFO', idUserdataAbfallVerzeichnis + '.' + String(i) + '.date', true, { type: 'string', role: 'weather.title', name: { de: 'INFO', en: 'INFO' } }); + log('Fertig', 'info') + } else { + log('Datenpunkt ' + idUserdataAbfallVerzeichnis + '.' + String(i) + ' vorhanden', 'info') + } + } + log('Startabfrage der Daten', 'info'); + JSON_auswerten(); + } catch (err) { + log('error at function Init_Datenpunkte: ' + err.message, 'warn'); + } +} +Init_Datenpunkte(); + +// --------------------------- Ende Funktion Datenpunkte ------------------------------------------------ + + +// --------------------------- Zusatzfuktionen ------------------------------------------------------------- +function currentDate() { + let d: Date = new Date(); + return new Date(d.getFullYear(), d.getMonth(), d.getDate()); +} + +function rgb_dec565(rgb: RGB): number { + //return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31))); + return ((rgb.red >> 3) << 11) | ((rgb.green >> 2)) << 5 | ((rgb.blue) >> 3); +} + +function hex_rgb(colorhex: string): RGB { + let r = parseInt(colorhex.substring(1, 3), 16); + let g = parseInt(colorhex.substring(3, 5), 16); + let b = parseInt(colorhex.substring(5, 7), 16); + return { red: r, green: g, blue: b }; +} + +type RGB = { + red: number, + green: number, + blue: number +}; + +// -------------------- Ende Zudatzfunktionen -------------------------------------------------------------------------- diff --git a/ioBroker/Blockly/CardChart_History.js b/ioBroker/Blockly/CardChart_History.js new file mode 100644 index 00000000..2cc66fc0 --- /dev/null +++ b/ioBroker/Blockly/CardChart_History.js @@ -0,0 +1,50 @@ +var sourceDP = 'alias.0.Wohnzimmer.Heizung.ACTUAL'; +var targetDP = '0_userdata.0.Test.chartTest'; +var rangeHours = 24; +var maxXAchsisTicks = 6; +var historyInstance = 'history.0'; + +on({id: sourceDP, change: "any"}, async function (obj) { + sendTo(historyInstance, 'getHistory', { + id: sourceDP, + options: { + start: Date.now() - (60 * 60 * 1000 * rangeHours), + end: Date.now(), + count: rangeHours, + limit: rangeHours, + aggregate: 'average' + } + }, function (result) { + var cardChartString = ""; + var stepXAchsis = rangeHours / maxXAchsisTicks; + + for (var i = 0; i < rangeHours; i++){ + var deltaHour = rangeHours - i; + var targetDate = new Date(Date.now() - (deltaHour * 60 * 60 * 1000)); + + //Check history items for requested hours + for (var j = 0, targetValue = 0; j < result.result.length; j++) { + var valueDate = new Date(result.result[j].ts); + var value = (Math.round(result.result[j].val * 10) / 10); + + if (valueDate > targetDate){ + if ((targetDate.getHours() % stepXAchsis) == 0){ + cardChartString += targetValue + '^' + targetDate.getHours() + ':00' + '~'; + } else { + cardChartString += targetValue + '~'; + } + break; + } else { + targetValue = value; + } + } + } + + cardChartString = cardChartString.substring(0,cardChartString.length-1); + if (existsState(targetDP) == false ) { + createState(targetDP, cardChartString, true, { type: 'string' }); + } else { + setState(targetDP, cardChartString, true); + } + }); +}); \ No newline at end of file diff --git a/ioBroker/Blockly/CardLChart_History.js b/ioBroker/Blockly/CardLChart_History.js new file mode 100644 index 00000000..9f3d0dc3 --- /dev/null +++ b/ioBroker/Blockly/CardLChart_History.js @@ -0,0 +1,78 @@ +const sourceDP = 'alias.0.Wohnzimmer.Heizung.ACTUAL'; +const targetDP = '0_userdata.0.Test.chartTest'; +const numberOfHoursAgo = 24; // Period of time in hours which shall be visualized +const xAxisTicksEveryM = 60; // Time after x axis gets a tick in minutes +const xAxisLabelEveryM = 240; // Time after x axis is labeled in minutes +const historyInstance = 'history.0'; + +const Debug = false; +const maxX = 1420; +const limitMeasurements = 35; + +createState(targetDP, "", { + name: 'SensorGrid', + desc: 'Sensor Values [~