NEWS
[Vorlage] Generisches Zählscript
-
Hi,
Bisher hatte ich ein Zählscript im Einsatz, dass bei Änderungen auch immer Codingänderungen zur Folge hatte.
Dies ist bei dem hier vorgestellten Zaehlscript nicht so, da die meisten Parameter einstellbar sind.Das Script ist recht variabel. Allerdings erfordert es auch Klarheit bezüglich der Selektion der Kanäle (was in Homematic den Gewerken entspricht). Ich habe z.B. bei mir auch meine Hue so eingebunden, die eben keine Homematic Geräte sind.
Die aktiven Geräte werden in beliebig zu definierende Datenpunkte abgelegt inclusive Text oder JSON Datenpunkte. Damit sind diese auch in VIS gut darstellbar.
Die Logik ist nicht fest verdrahtet sondern einstellbar. Daher ist es ein generisches Script
Was macht das Script ?
Es überprüft für zu definierende Datenpunkte ob ein Gerät eingeschaltet ist und speichert die Anzahl der Geräte, die eingeschaltet sind in die definierten Datenpunkte.
Diese Datenpunkte können dann in VIS genutzt werden, um z.B. zu Zeigen wieviel Leuchten gerade eingeschaltet sind und welche das sind.Die relevanten Datepunkte werden so ausgewertet:
- Datenpunkt = true --> Gerät eingeschaltet (z.B. bei Lampen, Fenster, Bewegungsmelder etc)
- Datenpunkt > 0 --> Gerät eingeschaltet (z.B. bei Dimmer, Hue-Leuchten, Rollladen etc)
Zur Einstellung sind 3 Tabellen zu definieren:
- Datenpunkte
hier werden die Anzahl Geräte Total und auch eingeschaltete Geräte gespeichert.
Beispiel: 5 Rolladen Total davon sind 2 hochgefahren - Gruppierungen
hier können Geräte unterschiedlicher Herkunft z.B. Dimmer oder Hue-Leuchten zu Gruppen wie z.B. Leuchten zusammengefasst werden. Normales licht, sowie Dimmer oder Hue Leuchten gehören im Prinzip ja im allgemeinen zu „Leuchten“ - Selektoren
Selektoren sind die Filter die definiert werden müssen um die entsprechenden Geräte zu finden und zu subscriben (also zu reagieren, wenn es eine Zustandsänderung gibt)
für die meisten Fälle sollten die vordefnierten selektoren genügen.
Allerdings ist darauf zu achten, dass die functions in den selektoren auch dem entspricht was sich in den objekten wiederfindet.
im Prinzip ist es ein Filter auf die Objekte, was ja auch durch die Objektliste dann nachvollziebar ist
Für mich ein wichtiges Script, dass flexibel ist und effizient. Die Verbindung zu VIS macht es extrem hilfreich.
Beispiel:Summendarstellung:
Beispiel: Einzeldarstellung:
Ich hoffe, dass es dem einen oder anderen Anregung ist. Fragen sind natürlich willkommen.
hier das script:
zaehlscriptV4-8.txt
vG Looxer -
Hi,
ich habe eine verbesserte Version hochgeladen mit flexiblen Gruppierungen und eine kurze Erklärung der Funktion hinzugefügt.
vG Looxer -
Hi,
eine neue Version und wahrscheinlich final ist nun hochgeladen.
Es beinhaltet die Möglichkeit in eine Excel Datei (CSV) zu loggen.Ich bin nicht sicher, ob solche Vorlagen überhaupt noch interessant sind.
Rückmeldungen sind ja bisher eher gering bis gar nicht.
Für alles einen Adapter zu entwickeln macht aus meiner Sicht nicht unbedingt Sinn.
Vermutlich sind aber viele mit Blockly unterwegs.vG Looxer
-
Hallo, mal getestet. Kommen einige Fehler:
javascript.0 2024-09-22 21:11:18.248 error at createState (C:\SmartHome\node_modules\iobroker.javascript\lib\sandbox.js:2987:34) javascript.0 2024-09-22 21:11:18.248 error at Object.<anonymous> (script.js.Test.Fenster:215:175) javascript.0 2024-09-22 21:11:18.248 error at checkIfAllCreated (script.js.Test.Fenster:222:13) javascript.0 2024-09-22 21:11:18.248 error at script.js.Test.Fenster:83:5 javascript.0 2024-09-22 21:11:18.248 error at initializeCounts (script.js.Test.Fenster:233:28) javascript.0 2024-09-22 21:11:18.248 error at Array.forEach (<anonymous>) javascript.0 2024-09-22 21:11:18.248 error at script.js.Test.Fenster:234:9 javascript.0 2024-09-22 21:11:18.248 error at Count (script.js.Test.Fenster:154:5) javascript.0 2024-09-22 21:11:18.248 error at logResult (script.js.Test.Fenster:190:119) javascript.0 2024-09-22 21:11:18.248 error Error in callback: TypeError: Cannot read properties of undefined (reading 'name') javascript.0 2024-09-22 21:11:18.247 error script.js.Test.Fenster: getObject has been called with id of type "object" but expects a string javascript.0 2024-09-22 21:11:18.230 info script.js.Test.Fenster: registered 2 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions javascript.0 2024-09-22 21:11:18.229 info script.js.Test.Fenster: Alle Namen stimmen überein. javascript.0 2024-09-22 21:11:18.226 info script.js.Test.Fenster: javascript.0 2024-09-22 21:11:18.226 info script.js.Test.Fenster: Ende der MOTION-Liste javascript.0 2024-09-22 21:11:18.226 info script.js.Test.Fenster: Liste der MOTION-Geräte: javascript.0 2024-09-22 21:11:18.226 info script.js.Test.Fenster: javascript.0 2024-09-22 21:11:18.226 info script.js.Test.Fenster: Ende der Fenster-Liste javascript.0 2024-09-22 21:11:18.226 info script.js.Test.Fenster: Liste der Fenster-Geräte: javascript.0 2024-09-22 21:11:18.226 info script.js.Test.Fenster: javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: Ende der Rolladen-Liste javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: Liste der Rolladen-Geräte: javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: Ende der Hue-Liste javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: Liste der Hue-Geräte: javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: Ende der Brunnen-Liste javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: Liste der Brunnen-Geräte: javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: javascript.0 2024-09-22 21:11:18.225 info script.js.Test.Fenster: Ende der Dimmer-Liste javascript.0 2024-09-22 21:11:18.215 info script.js.Test.Fenster: Liste der Dimmer-Geräte: javascript.0 2024-09-22 21:11:18.215 info script.js.Test.Fenster: javascript.0 2024-09-22 21:11:18.215 info script.js.Test.Fenster: Ende der Lampen-Liste javascript.0 2024-09-22 21:11:18.214 info script.js.Test.Fenster: Liste der Lampen-Geräte: javascript.0 2024-09-22 21:11:18.148 info Start JavaScript script.js.Test.Fenster (Javascript/js) javascript.0 2024-09-22 21:11:18.142 info Stopping script script.js.Test.Fenster admin.0 2024-09-22 21:11:14.680 info ==> Connected system.user.admin from ::1
-
@sigi234
Hi,scheint, dass was im Konfigurationsbereich was nicht stimmt.
kannst du mal den Einstllungsbereich posten ?vG Looxer
-
@looxer01 sagte in [Vorlage] Generisches Zählscript:
@sigi234
Hi,scheint, dass was im Konfigurationsbereich was nicht stimmt.
kannst du mal den Einstllungsbereich posten ?vG Looxer
// Einstellungsbereich // Datenpunkte werden automatisch angelegt. Muss im Javascript Tree erfolgen, zwingend count, active, text und status müssen angelegt werden // Pfade für die Zählungsergebnisse // Achtung in allen 3 Tabellen muss Groß und Kleinschreibung berücksichtigt werden. Wenn in paths z.B. "MOTION" definiert ist, dann muss so auch in selectors definiert werden const paths = { Leuchten: { count: 'javascript.0.Counts.Leuchten.anzahlLichter', active: 'javascript.0.Counts.Leuchten.anzahlLichterAn', text: 'javascript.0.Counts.Leuchten.textLichterAn', status: 'javascript.0.Counts.Leuchten.Statusliste' }, Fenster: { count: 'javascript.0.Counts.Fenster.anzahlFenster', active: 'javascript.0.Counts.Fenster.anzahlFensterauf', text: 'javascript.0.Counts.Fenster.textFensterauf', status: 'javascript.0.Counts.Fenster.Statusliste' }, Rolladen: { count: 'javascript.0.Counts.Rolladen.anzahlRolladen', active: 'javascript.0.Counts.Rolladen.anzahlRolladenauf', text: 'javascript.0.Counts.Rolladen.textRolladenauf', status: 'javascript.0.Counts.Rolladen.Statusliste' }, MOTION: { count: 'javascript.0.Counts.Motion.anzahlMotion', active: 'javascript.0.Counts.Motion.anzahlMotionAktiv', text: 'javascript.0.Counts.Motion.textMotionAktiv', status: 'javascript.0.Counts.Motion.Statusliste' }, Brunnen: { count: 'javascript.0.Counts.Brunnen.anzahlBrunnen', active: 'javascript.0.Counts.Brunnen.anzahlBrunnenAn', text: 'javascript.0.Counts.Brunnen.textBrunnenAn', status: 'javascript.0.Counts.Brunnen.Statusliste' } // Weitere Daenpunkte können hier hinzugefügt werden / löschen von Datenpunkten falls nicht benötigt }; // Array für benutzerdefinierte Zusammenfassungen in die Zuvor definierten Datenpunkte, z.B. Dimmer Hue Lampen // Der name wird gemapped mit den Namen in der Tabelle paths - bedeutet die 3 Selektoren "Lampen,Dimmer,Hue" werden im Pfad unter "Leuchten" zusammengefasst. // Beispielsweise könnten auch Fenster und Rolladen zusammengefasst werden const groupings = { Leuchten: ['Lampen', 'Dimmer', 'Hue'], // "Lampen und Dimmer und Hue werden unter Leuchten zusammengefasst" // Weitere Zusammenfassungen können hier hinzugefügt werden / falls keine Groupings benötigt werden, dann ersetzen mit const groupings = [] }; // Selectoren sind eine Art Filter um die richtigen Datenpunkte zu finden, die dann subscribed werden // Functions in iobroker entsprechen Gewerke in Homematic // Achtung die Namen aus den Datenpunkten muessen exakt mit den hier verwendeten Namen übereinstimmmen: also z.B. MOTION = MOTION // der update der Hue lampen dauert etwas länger, da die updates über die Hue-Bridge relativ langsam sind const selectors = { Lampen: $('channel[state.id=*.STATE](functions=Licht)'), // allen Leuchten wurde das Gewerk "Licht zugeordnet aber nur für den relevanten Kanal in Homematic" Dimmer: $('channel[state.id=*.LEVEL](functions=Licht)'), Brunnen: $('channel[state.id=*.STATE](functions=Brunnen)'),// allen Pumpen wurde das Gewerk "Brunnen zugeordnet aber nur für den relevanten Kanal in Homematic" Hue: $('channel[state.id=hue.0.*.on](functions=Hue)'), // in der objektliste habe ich den channels (Hue-Leuchten) die Funktion "Hue" zugeordnet Rolladen: $('channel[state.id=*.LEVEL](functions=Rollade)'),// allen Rollladen wurde das Gewerk "Rollade" zugeordnet aber nur für den relevanten Kanal in Homematic" Fenster: $('channel[state.id=*.STATE](functions=Verschluss)'), MOTION: $('channel[state.id=*.MOTION](functions=Sicherheit)') // Weitere Selektoren können hier hinzugefügt werden / löschen von Selektoren falls nicht benötigt } const ReCreateSubscriptionsonNEW = true; // bei Erkennung neuer Geräte werden subscriptions neu erstellt (Erkennung geht nur bei Homematic) const debug = true; const listSelectors = true; // listet das Ergebnis der Selektoren beimn Start des Programmes- dient zum Fehler finden falls die Zählung nicht funktioniert const logObjects = ['MOTION']; // die hier angegebenen Objekte (aus den selectors) werden in einer excel-lesbaren Datei geloggt // Weitere Objekte können hinzugefügt werden, z.B. const logObjects = ['MOTION','Fenster']; oder keine Objekte: const logObjects = [] // Ende Einstellungsbereich
System:
Plattform: Windows
RAM: 15.9 GB
Node.js: v20.17.0
NPM: 10.8.2
Admin: 7.1.3
JS-Controller: 6.0.11
JS Skript: 8.8.3 -
@sigi234
Danke dir.
Deine Sucht bringt teilweise keine Ergebnisse was nicht abgefangen war.
Deine Gewerke werden vermutlich anders benannt. Die Suchliste im Protokoll zeigt ja auch keine Ergebnisse.Ist korrigiert mit Version 4.1 oben im ersten post.
vG Looxer
-
@looxer01 sagte in [Vorlage] Generisches Zählscript:
@sigi234
Danke dir.
Deine Sucht bringt teilweise keine Ergebnisse was nicht abgefangen war.
Deine Gewerke werden vermutlich anders benannt. Die Suchliste im Protokoll zeigt ja auch keine Ergebnisse.Ist korrigiert mit Version 4.1 oben im ersten post.
vG Looxer
Ok, Fehler weg aber keine Geräte gefunden?
Muss man den Ganzen Kanal die Funktion zuweisen?
-
@sigi234 sagte in [Vorlage] Generisches Zählscript:
Muss man den Ganzen Kanal die Funktion zuweisen?
Ich Antworte mir mal selber:
JA
-
die Suche definierst du selbst. In deinem Fall
Lampen: $('channel[state.id=*.STATE](functions=Licht)'), // allen Leuchten wurde das Gewerk "Licht zugeordnet aber nur für den relevanten Kanal in Homematic" Dimmer: $('channel[state.id=*.LEVEL](functions=Licht)'),
suchst du nach allen Geräten mit der Rolle "State" und dem Gewerk "Licht"
Diese sind aber nicht so in der objektliste definiert.Du hast im Datenpunt "...on" Rolle Switch und Gewerk Hue und auch Licht definiert.
vG Looxer
-
noch mal zurück. Habe spät gemerkt, dass es ja um die Hue geht
Hue: $('channel[state.id=hue.0.*.on](functions=Hue)')
bei mir sieht es so aus. was auch funktioniert:
Die Suche erfolgt also über die Datenpunkte die unter "Hue.0" liegen. (ist das bei dir der Fall ?)
dann noch die darunterliegenden Datenpunkte die mit "on" enden
der dann der Funktion "Hue" zugeordnet ist.Habs nie getestet aber ich glaube dass damit tatsächlich der Kanal komplett zugeordnet werden muss, weil sonst die Suchbedingung nicht zutrifft.
vG Looxer
-
@looxer01 sagte in [Vorlage] Generisches Zählscript:
noch mal zurück. Habe spät gemerkt, dass ja um die Hue geht
Hue: $('channel[state.id=hue.0.*.on](functions=Hue)')
Die Suche erfolgt also über die Datenpunktke die unter "Hue.0" liegen. (ist das bei dir der Fall ?)
dann noch die darunterliegenden Datenpunkte die mit "on" enden
die dann der Funktion "Hue" zugeordnet ist.Ja
Habs nie getestet aber ich glaube dass damit tatsächlich der Kanal komplett zugeordnet werden muss, weil sonst die Suchbedingung nicht zutrifft.
Ja
-
es gibt eine angepasste Version 4.3
kleine Korrektur beim Aufruf der Initalisierung wenn debug eingeschaltet ist
Das angepasste Script befindet sich im ersten Post -
@looxer01 im Skript nutzt du "javascript.0.". Wäre nicht "0_userdata.0." besser?
Ro75.
-
@ro75
Hi,
ich persönlich habe alle meine script-relevanten Datenpunkte unter javascript.
aber wer das gerne unter userdata hat, kann ja einfach die states entsprechend umbenennen. (Einstellungsbereich)
Das Script sollte damit keine Probleme haben. Lässt sich ja auch jederzeit ändern.vG Looxer
-
Kann man die Anzeige der Namen ändern?
-
@sigi234
Hi,
also die Codezeile steht hier:
jsonString += createJsonEntry(selectorType, object.common.name, status);Die Info steht also in comon.name des datenpunktes.
Eigentlich sollte das doch immer die Beschreibung sein ?
(manchmal etwas hölzern aber immer zutreffend)oder welches Datenelement wäre alternativ besser ? (ausser manuelle Zuordnung)
Wäre es eine Lösung nur den Text bis zum ersten Punkt zu übertragen ?vG Looxer
-
@looxer01 sagte in [Vorlage] Generisches Zählscript:
Wäre es eine Lösung nur den Text bis zum ersten Punkt zu übertragen ?
Denke schon
-
@sigi234
magst du folgendes versuchen ?//----------------------------------------------------------------------------------------- // Function createJsonEntry - Routine erzeugt Json record //----------------------------------------------------------------------------------------- function createJsonEntry(type, Name, status) { let CleanName = Name.split('.')[0]; return `{"Type":"${type}","Ort":"${CleanName}","Status":"${status}"},`; }
den Block komplett ersetzen.
vG Looxer
-
@looxer01 sagte in [Vorlage] Generisches Zählscript:
@sigi234
magst du folgendes versuchen ?
den Block komplett ersetzen.Leider keine Änderung:
javascript.0 13:09:02.487 info Stopping script script.js.Test.Fenster javascript.0 13:09:02.491 info Start JavaScript script.js.Test.Fenster (Javascript/js) javascript.0 13:09:02.507 info script.js.Test.Fenster: Liste der Lampen-Geräte: javascript.0 13:09:02.507 info script.js.Test.Fenster: Ende der Lampen-Liste javascript.0 13:09:02.507 info script.js.Test.Fenster: javascript.0 13:09:02.507 info script.js.Test.Fenster: Liste der Dimmer-Geräte: javascript.0 13:09:02.507 info script.js.Test.Fenster: Ende der Dimmer-Liste javascript.0 13:09:02.507 info script.js.Test.Fenster: javascript.0 13:09:02.507 info script.js.Test.Fenster: Liste der Hue-Geräte: javascript.0 13:09:02.507 info script.js.Test.Fenster: - ID: hue.0.Bad.on | Name: Bad.on javascript.0 13:09:02.507 info script.js.Test.Fenster: - ID: hue.0.Büro.on | Name: Büro.on javascript.0 13:09:02.507 info script.js.Test.Fenster: - ID: hue.0.Garten.on | Name: Garten.on javascript.0 13:09:02.507 info script.js.Test.Fenster: - ID: hue.0.Hue_lightstrip_Küche.on | Name: Hue lightstrip Küche.on javascript.0 13:09:02.507 info script.js.Test.Fenster: - ID: hue.0.WC.on | Name: WC.on javascript.0 13:09:02.507 info script.js.Test.Fenster: Ende der Hue-Liste javascript.0 13:09:02.507 info script.js.Test.Fenster: javascript.0 13:09:02.508 info script.js.Test.Fenster: Liste der Fenster-Geräte: javascript.0 13:09:02.508 info script.js.Test.Fenster: - ID: hm-rpc.0.NEQ1818500.1.STATE | Name: Haustuer.STATE javascript.0 13:09:02.508 info script.js.Test.Fenster: - ID: hm-rpc.0.NEQ1826414.1.STATE | Name: Terrassentuer.STATE javascript.0 13:09:02.508 info script.js.Test.Fenster: - ID: hm-rpc.0.OEQ0926852.1.STATE | Name: Badfenster.STATE javascript.0 13:09:02.508 info script.js.Test.Fenster: Ende der Fenster-Liste javascript.0 13:09:02.508 info script.js.Test.Fenster: javascript.0 13:09:02.508 info script.js.Test.Fenster: Liste der MOTION-Geräte: javascript.0 13:09:02.508 info script.js.Test.Fenster: Ende der MOTION-Liste javascript.0 13:09:02.508 info script.js.Test.Fenster: javascript.0 13:09:02.508 info script.js.Test.Fenster: Alle Namen stimmen überein. javascript.0 13:09:02.508 info script.js.Test.Fenster: registered 10 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions javascript.0 13:09:02.511 info script.js.Test.Fenster: Anzahl Leuchten: 5 | Leuchten aktiv: 3 | Auslöser: Initial | Status: null javascript.0 13:09:02.511 info script.js.Test.Fenster: Anzahl Fenster: 3 | Fenster aktiv: 1 | Auslöser: Initial | Status: null javascript.0 13:09:02.512 info script.js.Test.Fenster: Anzahl MOTION: 0 | MOTION aktiv: 0 | Auslöser: Initial | Status: null