Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. BananaJoe

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Profile
    • Following 25
    • Followers 13
    • Topics 63
    • Posts 5242
    • Best 863
    • Groups 3

    BananaJoe

    @BananaJoe

    Most Active

    1032
    Reputation
    379
    Profile views
    5242
    Posts
    13
    Followers
    25
    Following
    Joined Last Online
    Website znil.net Location Achim bei Bremen Age 52

    BananaJoe Follow
    Pro Starter Most Active

    Best posts made by BananaJoe

    • RE: Bestückung Netzwerkschrank (Neubau)

      @chillkroete1206 also Patchpanel mit 48 Ports .. wird schon ein Mörder Teil wenn da dann 48 (44) Cat. 7 Kabel von hinten dran kommen. Überlege dir die Kabelführung, das wird ein ordentlicher Strang. Den du nie wieder bewegen kannst. Also so legen das da nichts verdeckt wird wo du noch mal ran müsstest oder du noch mal ein Loch durchbohren würdest.

      Ich habe es zu Hause auf 2 x 24 Patchpanel verteilt + Kabelführung. Dazu ist nachträglich noch ein 16er Patchfeld gekommen (Datenkabel aus Garage nachverlegt usw.) Sind bei mir im Reihenhaus 56 aktive Anschlüsse.

      Thema Switch: Wir sind zu 4 in einem Reihenhaus, was braucht man da schon an Leitungen ...
      mhh, der 24 + 4 Port Switch ist voll, der 8 + 2 Port PoE ist fast voll, der 16 Port Netgear ist auch voll ... es sammelt sich (5 VoIP Telefone, 5 AccessPoints, 4 FireTV-Sticks (alle mit LAN Adapter) + 2 Fernseher, Playstation, 4 Laptops, Computer, Server mit 2fach Trunk, 2 x selbst-bau ESXi, 2 x Raspberry Pi (1 x ESXi, 1x KVM), 1 x Backups-NAS mit Trunk, 12 Kameras (auch wenn nicht alle in Betrieb sind weil sinnfrei wie die Kamera über dem Brotbackautomat) ...

      Die Patchfelder im Schrank wollen auch alle geführt werden (ich nutze inzwischen flache 5x1mm Patchkabel, das kurze Stück geht das). Ich würde Platz für das Kabelrangieren einplanen mit einem HE drüber und drunter.
      Und auch eine Steckdosenleiste vorne. Ich habe auch eine hinten an die ich inzwischen quasi gar nicht mehr ran komme.
      Ich hab sogar seitlich ein Loch in den Schrank geschnitten (nach 8 Jahren nachträglich) um überhaupt hinten noch mal an was ranzukommen. In das Loch habe ich 2 x 120mm USB Lüfter gepackt (auf niedriger Drehzahl), seitdem sind meine lüfterlosen Switche auch nicht mehr heiß.
      Und meine Steckdosenleiste vorne ist inzwischen so voll das da schon 2 x 7 Port hängen. (Zu dem Server + ESXi`s + Raspis kommen noch Netzteil für USB Lüfter, Lampe im Schrank, Netzteil Klingelpaul und ESP8266 zur Auswertung vom Klingelpaul, 1x Fritzbox alt und 1 x neu und die dritte kommt mit dem Glasfaseranschluß.

      Sei also sehr sehr großzügig. Bei allen. Und du kannst dir vorstellen was das für ein riesen Kabelsalat wird (und ist), also auch bitte schon gleich alles Beschriften, jedes Kabel, Patchkabel, Stromkabel, Koaxialkabel, immer an beiden Enden! Es gibt da schöne Klebeetiketten für diese Zwecke. Ich habe da heute noch Patchkabel drin von denen ich nicht mehr weis wo diese Enden (muss irgendwas aus dem gleichen Raum sein, aber keine 10 Jahre später vergessen wofür). Vergiss das schöne Bündeln von Stromanschluss- oder Datenkabeln, das wird schneller auseinander gerissen als du denkst, habe lieber Platz das du so ein Kabel auch wieder rausbekommst. Spätestens wenn du das erste mal ein Kabel das nicht mehr gebraucht wird nicht gleich wieder rausziehst hast du später verloren (Stichwort "Vergessen wofür" oder "Was war jetzt AEG?". Und du wird welche rausziehen.

      Ach ja, und schwarze Kunststoff-Quader, hatte ich schon von schwarzen Kunststoffquadern erzählt? Werden auch Netzteile genannt. Erst hast du einen Switch mit Kaltgeräteanschluss, der wird getauscht und der nächste kommt mit einem schwarzen Kunststoffquader. Habe ich erwähnt das du den gleich und sofort beschriften solltest wofür der ist? Das dann der Zeitpunkt ist wo du ein Kaltgerätekabel wieder rauspulen, ein Euro-Stecker-Kabel neu verlegen und irgendwo diesen Quader lassen musst?

      Hatte ich eigentlich erwähnt das du extra Platz einplanen solltest? Viel extra Platz. Ganz viel extra Platz. Für Kabelführung, die Möglichkeit ein Kabel auch wieder raus zu ziehen? Für schwarze Quader? Das dann doch neue extra NAS (nur echt mit extra Quader!) .. und das PVR System und das nur mal ausprobieren Ding ...

      Hatte ich schon USV erwähnt? Ein großer schwarzer Kunststoffblock? An den du die Steckdosenleisten hoffentlich alle anschließt? Und der erste Test, prima, hält 30 Minuten das Ding. Öhm, 2 Jahre später beim Stromausfall merkst du das plötzlich nur noch 3 Minuten sind wegen der vielen schwarzen Stromkabel und Quader ... hatte ich erwähnt das du Reserveplatz brauchst, z.B. für die 2. USV?

      Ok, ok, ich hab mich etwas in Rage geschrieben 🙂 Ich hoffe die Botschaft kommt an.

      Bei den Datendosen werden es die ausgewählten Dosen mit LSA-Plus tun. Die baust du nur einmal ein und fast die nie wieder an. Tu dir einen gefallen und nimm tiefe Einbaudosen. Inzwischen gibt es sogar tiefe Einbaudosen mit Tasche nach unten.

      Wenn die Neugier plagt: Ich wollte damals in der "Waschküche" einen 12HE Wandschrank aufhängen, so 400mm tief. Der wurde von meiner Frau nicht genehmigt "weil der zu viel Platz wegnimmt".
      Ich hatte in der alten Wohnung noch einen 40HE Datenschrank, 600mm breit, 800mm tief den ich schwarz gestrichen und als Vitrine genutzt hatte. Den habe ich mir in mein Kellerbüro gestellt:
      502477a5-1c53-4e1d-ad7f-fa83ba361bc0-Datenschrank1.jpg

      posted in Hardware
      BananaJoe
      BananaJoe
    • [Vorlage] Schimpfwortgenerator

      Changelog:

      • 04.10.2024 erste Version
      • 05.10.2024 Variante die 1x die Minute ein Schimpfwort in einen Datenpunkt schreibt ergänzt
      • 05.10.2024 Fehler im Skript für Datenpunkt behoben (aktualisiere statt steuere da Datenpunkt schreibgeschützt)
      • 21.10.2024 Bereinigte Schimpfwortliste (Danke an @JoJo58 )

      Ich bin über dieses Projekt hier gestolpert: https://github.com/NikolaiRadke/Schimpfolino/wiki

      Ich nutze bei uns im Smarthome einige Sprachausgaben über Alexa, z.B. "Waschmaschine ist fertig" oder "Mittagessen" usw.
      Diese wollte ich mit dem Schimpfwortgenerator etwas aufpolieren und habe mir deshalb eine JavaScript-Funktion für Blockly dafür gebaut:
      1d12dc55-68e7-4b99-83a3-9b70bef21194-image.png
      Die Wortlisten habe ich aus dem Projekt entnommen, ebenso das Funktionsprinzip der Ermittlung welches im dazu gehörigen Make-Magazin Artikel genau erklärt wird: https://www.heise.de/ratgeber/Roboter-im-Eigenbau-Teil-1-Ein-Schimpfwortgenerator-9857007.html?seite=all
      Export:

      <block xmlns="https://developers.google.com/blockly/xml" type="procedures_defcustomreturn" id="h!J2T(,rRS$uRe+#Tw8y" x="38" y="-337">
        <mutation statements="false"></mutation>
        <field name="NAME">Schimpfwortgenerator</field>
        <field name="SCRIPT">Ly8gRnJlaSBuYWNoIGh0dHBzOi8vZ2l0aHViLmNvbS9OaWtvbGFpUmFka2UvU2NoaW1wZm9saW5vL3dpa2kNCg0KLy8gVGVpbCAxOiBXb3J0bGlzdGVuIGRlZmluaWVyZW4NCnZhciBhX3dvcnRsaXN0ZTEgPSBbIkR1bXBmZSIsIlN0YXViaWdlIiwiTWllZmVuZGUiLCJTdGlua2VuZGUiLCJHYW1tbGlnZSIsIkhpbmtlbmRlIiwiV2luemlnZSIsIlBvcGVsaWdlIiwiTmFzc2UiLCJGdXJ6ZW5kZSIsIlJvc3RpZ2UiLCJIb2hsZSIsIlNpZmZpZ2UiLCJNaWVzZSIsIktydW1tZSIsIktsYXBwcmlnZSIsIlRyb2NrZW5lIiwiSGFhcmlnZSIsIlVyYWx0ZSIsIkdydW56ZW5kZSIsIlNjaHJlaWVuZGUiLCJNZWNrZXJuZGUiLCJOZXJ2ZW5kZSIsIlNhYmJlcm5kZSIsIlRyaWVmZW5kZSIsIk1vZHJpZ2UiLCJMdW1waWdlIiwiTGF1c2lnZSIsIlNpbm5sb3NlIiwiT2xsZSIsIlVubsO2dGlnZSIsIkRhbXBmZW5kZSIsIkxlZHJpZ2UiLCJFaW5hcm1pZ2UiLCJMZWVyZSIsIkzDpHN0aWdlIiwiSGV1bGVuZGUiLCJQaWNrZWxpZ2UiLCJGYXVsZSIsIlJhbnppZ2UiLCJUcsO8YmUiLCJEcmFsbGUiLCJCbGFua2UiLCJHaWVyaWdlIiwiVHJhbmlnZSIsIldhY2tlbG5kZSIsIlRvcmtlbG5kZSIsIlfDvHN0ZSIsIkZpc2NoaWdlIiwiQmVrbmFja3RlIiwiVmVya29ya3N0ZSIsIkhlaW1saWNoZSIsIkzDtmNocmlnZSIsIkJyb2NraWdlIiwiUGx1bXBlIiwiVGF0dHJpZ2UiLCJSYXR0ZXJuZGUiLCJTY2htdXR6aWdlIiwiTGlkZXJsaWNoZSIsIkTDtnNpZ2UiLCJQcm9sbGlnZSIsIkZpZXNlIiwiTXVmZmlnZSIsIk3DvGZmZWxuZGUiLCJQZWlubGljaGUiLCJOw7ZyZ2VsbmRlIiwiRmV0dGlnZSIsIlphaG5sb3NlIiwiRnJlY2hlIiwiU2Now6RiaWdlIiwiUGllZmlnZSIsIkd1bW1pZ2UiLCJMYWJicmlnZSIsIlBhdHppZ2UiLCJQZWx6aWdlIiwiUmV1ZGlnZSIsIlBla2lnZSIsIk3DvHJiZSIsIkhhcnppZ2UiLCJMYWhtZSIsIk1pY2tyaWdlIiwiQnLDpHNpZ2UiLCJab3R0ZWxpZ2UiLCJHZWxibGljaGUiLCJLbm9ycmlnZSIsIlNhbHppZ2UiLCJTY2hyaWxsZSIsIkR1c3NlbGlnZSIsIldpbmRpZ2UiLCJHcmF1c2lnZSIsIkdyw6Rzc2xpY2hlIiwiR3JvYmUiLCJTcGFja2lnZSIsIkthdXppZ2UiLCJGbGFjaHNpZ2UiLCJGcmFuc2lnZSIsIk1vdHppZ2UiLCJLYWhsZSIsIk5pZWRyaWdlIiwiS2VpZmVuZGUiLCJOaWNodGlnZSIsIkRyw7ZnZSIsIkZhZGUiLCJXZWluZW5kZSIsIkhpYmJlbGlnZSIsIlBsb2NraWdlIiwiQnJlbm5lbmRlIiwiRMO8cnJlIiwiS29jaGVuZGUiLCJLbmFyemVuZGUiLCJGYWx0aWdlIiwiU2NobGFtbWlnZSIsIkJyw7Zja2VsaWdlIiwiUmlzc2lnZSIsIlZlcmtlaW10ZSIsIkthbnRpZ2UiLCJHZWtsYXV0ZSIsIlF1aWVja2VuZGUiLCJGYXNlbG5kZSIsIkJlaXNzZW5kZSIsIkdlaMO2cm50ZSIsIlZlcmdlc3NlbmUiLCJCbGVpY2hlIiwiWndlaWNrZW5kZSIsIkZyb3N0aWdlIiwiTmFja2lnZSIsIkdydXNlbGlnZSIsIk1pbmRlcmUiLCJIYWdlcmUiLCJNYWdlcmUiLCJTY2h1cHBpZ2UiLCJCZWxlZ3RlIiwiU3TDpG5rZXJuZGUiLCJCw7ZzYXJ0aWdlIiwiUm9sbGVuZGUiLCJTY2hlY2tpZ2UiLCJSdWJiZWxuZGUiLCJTY2hpZWxlbmRlIiwiVHJhdHNjaGlnZSIsIkdyb3Rlc2tlIiwiQWJzdXJkZSIsIk1laGxpZ2UiLCJQbGF0dGUiLCJNw7xkZSIsIlRvdGFsZSIsIkJla2xvcHB0ZSIsIlNjaGF1cmlnZSIsIlRhdWJlIiwiQmV0w6R1YnRlIiwiQmVow6RtbWVydGUiLCJCZWxhbmdsb3NlIiwiQmVsZWlkaWd0ZSIsIkJldHJ1bmtlbmUiLCJCaXphcnJlIiwiRGlmZnVzZSJdOw0KdmFyIGFfd29ydGxpc3RlMiA9IFsiU3RhbXBmIiwiV2FiYmVsIiwiUHVwcyIsIlNjaG1hbHoiLCJTY2htaWVyIiwiSGFjayIsIlplbWVudCIsIlNwdWNrIiwiU3RhY2hlbCIsIktlbGxlciIsIkxhYmVyIiwiU3RvY2siLCJSdW56ZWwiLCJTY2hydW1wZiIsIkVrZWwiLCJTY2hub2RkZXIiLCJNYXRzY2giLCJXdXJtIiwiRWl0ZXIiLCJTcGVjayIsIk1pc3QiLCJLbG90eiIsIlfDvHJnIiwiTHVtcGVuIiwiU2NobGVpbSIsIld1cnN0IiwiRG9vZiIsIkJyYXQiLCJTY2h3YW1tIiwiS3JhdHoiLCJHcm90dGVuIiwiS3JpZWNoIiwiR2lmdCIsIlNjaGxhYmJlciIsIkfDtmJlbCIsIktsZWIiLCJTY2htYWRkZXIiLCJHcmluZCIsIkxhYmJlciIsIkx1ZnQiLCJNYXNzZW4iLCJTY2hpbW1lbCIsIk1pbmkiLCJPY2hzZW4iLCJQcm9ibGVtIiwiUXVhc3NlbCIsIlNjaG5hcHMiLCJTYWZ0IiwiRnJpZW1lbCIsIlphcHBlbCIsIlRyb3BmIiwiUGx1bnRzY2giLCJTdW1wZiIsIkhlY2tlbiIsIkdyYWIiLCJTY2h3aXR6IiwiU2NobmFyY2giLCJTY2hsZWljaCIsIlNjaGx1ZmYiLCJGbMO2dGVuIiwiSG9seiIsIktyZWlzY2giLCJEdWxsaSIsIkx1c2NoZW4iLCJHYW1tZWwiLCJBbHTDtmwiLCJSw7ZjaGVsIiwiR2xpYmJlciIsIkxhY2giLCJLcmFjaCIsIktuaWNrIiwiUXVldHNjaCIsIlF1YXRzY2giLCJRdWlldHNjaCIsIktuYXV0c2NoIiwiVMO8bXBlbCIsIlRlaWNoIiwiS25hdHRlciIsIlNhdWYiLCJQaXBpIiwiU3RydWxsZXIiLCJHcsOkdGVuIiwiTmFzZW4iLCJQZWNoIiwiTGVpZXIiLCJSZWllciIsIkJsw7ZkIiwiU2Nob3JmIiwiU2FiYmVsIiwiUXVlbmdlbCIsIkJhbmFuZW4iLCJVbnNpbm5zIiwiUGx1bnNjaCIsIkZydXN0IiwiTG90dGVyIiwiRnVtbWVsIiwiQmx1YmJlciIsIldvYmJlbCIsIlZvbGxiYXJ0IiwiTGFjayIsIktsbyIsIk1vZGVyIiwiS25pcnNjaCIsIlppdHRlciIsIkthbHQiLCJTY2hsw7xyZiIsIlNjaG5pZWYiLCJLbGVja2VyIiwiUnVtYmEiLCJTY2h3dXJiZWwiLCJTY2hyYWJiZWwiLCJTY2hsYXVjaCIsIlNjaHJ1bXBlbCIsIkjDvGhuZXIiLCJTY2hsYWNrZXIiLCJCcmFiYmVsIiwiS3JhbXBmIiwiUHLDvGdlbCIsIlJhcHBlbCIsIlp1cHBlbCIsIlBsdW5kZXIiLCJEb25uZXIiLCJSaWVzZW4iLCJCdXR0ZXIiLCJXaXNjaHdhc2NoIiwiUG9sdGVyIiwiVHJhbXBlbCIsIlNhdWVyIiwiSGFtcGVsIiwiQml0dGVyIiwiTWFzc2VsIiwiRmxpdHoiLCJXYXJtIiwiU2NobGluZyIsIlBsdW1wcyIsIlF1w6RsIiwiU3RyYW1wZWwiLCJTY2hsZWNrIiwiUmVjeWNsaW5nIiwiRWdhbCIsIkJsZWNoIiwiSG9ycm9yIiwiUnVtcGVsIiwiU2NobnVsbGVyIiwiU2NoZXJ6IiwiTmFja3QiLCJQYW1wZWwiLCJNb3Jhc3QiLCJGbGFjaCIsIkFuZ3N0IiwiU3BlaSIsIlB1bXBlbCIsIkF1c3NjaGxhZyIsIlF1YWxtIiwiUmFtYmF6YW1iYSIsIktsZWluIiwiU3BydWRlbCJdOw0KdmFyIGFfd29ydGxpc3RlMyA9IFsic3VwcGUiLCJzb2NrZSIsImJvbWJlIiwiYm91bGV0dGUiLCJzY2h3YXJ0ZSIsIndhcnplIiwiYmV1bGUiLCJwZXN0IiwicGZsYXVtZSIsInLDvGJlIiwiZ2VpZ2UiLCJyYXR0ZSIsImtyYW5raGVpdCIsInd1bmRlIiwib21hIiwic3R1bGxlIiwibGllc2UiLCJicnV0IiwiaGVubmUiLCJ6d2llYmVsIiwiYnVkZSIsImtpc3RlIiwiYnJhdXQiLCJsZXVjaHRlIiwia3LDtnRlIiwibnVzcyIsInNwaW5uZSIsImdydWJlIiwidG9pbGV0dGUiLCJrcmFrZSIsInBmw7x0emUiLCJiYWNrZSIsImJyYXRzY2hlIiwia2xhdHNjaGUiLCJudWRlbCIsImtub2xsZSIsInTDvHRlIiwibmFzZSIsIm1hZGUiLCJ0b25uZSIsImtyYW1wZSIsImLDvHJzdGUiLCJ3aW5kZWwiLCJzZW1tZWwiLCJoYXhlIiwiZ3LDpGZpbiIsInNjaGxldWRlciIsInppZXJkZSIsImtyw6RoZSIsImxhdHRlIiwibmlldGUiLCJyYXNzZWwiLCJhc3NlbCIsInRvcnRlIiwiZ2FsbGUiLCJsYXRzY2hlIiwic2NocnVsbGUiLCJrYW5vbmUiLCJibGFzZSIsInBlbGxlIiwidHJpbmUiLCJxdWVlbiIsInplY2tlIiwicHJhbGluZSIsIm1hZ3QiLCJwcmFjaHQiLCJmcml0dGUiLCJzb3NzZSIsImxhcnZlIiwibXVybWVsIiwiaGV4ZSIsInBhbXBlIiwic2lyZW5lIiwiZHLDvHNlIiwia2xldHRlIiwicGV0emUiLCJicnVtbWUiLCJnbGF0emUiLCJxdWFsbGUiLCJuYXR0ZXIiLCJrcmFsbGUiLCJ6aWVnZSIsImdyw7x0emUiLCJzw7xsemUiLCJudWxwZSIsIndhbXBlIiwiZnJpa2FkZWxsZSIsImZsdW5kZXIiLCJ0cnVsbGEiLCJ6aWNodGUiLCJ1c2NoaSIsImt1aCIsInBhcHBlIiwiaHVwZSIsInRyw7Z0ZSIsInNjaGFiZSIsImthbmFsbGllIiwic2NoYXJ0ZSIsInJpbGxlIiwiYW1zZWwiLCJhbGdlIiwibMO8Y2tlIiwiYnJlbXNlIiwibcO8Y2tlIiwiYsO8cnN0ZSIsIndhbm5lIiwicG9ja2UiLCJwbMO2cnJlIiwic2NoYWJyYWNrZSIsInd1cHBlIiwic2ljaGVsIiwidGFudGUiLCJyZXVzZSIsInJhdHNjaGUiLCJwYXVrZSIsImZsdXBwZSIsIm1hdHJvbmUiLCJodW1tZWwiLCJwYXJhZGUiLCJhdHRyYXBwZSIsImzDvGdlIiwiZmxvc3NlIiwiZnVuemVsIiwiZ3Vya2UiLCJwaWVwZSIsImfDtnJlIiwia29sYmVuIiwic2FtbWx1bmciLCJwcmltZWwiLCJvbW1lIiwibG90dGUiLCJ1bmtlIiwic3RyaXBwZSIsInNlaWZlIiwicGzDtnR6ZSIsIndlc3BlIiwibGF3aW5lIiwidGFibGV0dGUiLCJrcsO8Y2tlIiwiZ3JhemllIiwiZGl2YSIsInB1bGxlIiwibmVzc2VsIiwia2FrZXJsYWtlIiwiZGlzdGVsIiwiYW3DtmJlIiwiZmFja2VsIiwiaMO8ZnRlIiwicnVpbmUiLCJ3YWNodGVsIiwic2V1Y2hlIiwia2lwcGUiLCJzY2hpcHBlIiwiZ2VzdGFsdCIsIndvbGtlIiwibXVtaWUiLCJzcHVyIiwiY3JlbWUiLCJtb3R0ZSJdOw0KdmFyIGFfd29ydGxpc3RlNCA9IFsiYnVzY2giLCJmaW5rIiwibmFnZWwiLCJiYW1tZWwiLCJrbG9wcGVyIiwidGVudGFrZWwiLCJicsOkZ2VuIiwic2NobHVtcGYiLCJodXN0ZW4iLCJlcnNhdHoiLCJoYXVmZW4iLCJrbsO2ZGVsIiwicsO8c3NlbCIsImhpbnRlcm4iLCJlaW1lciIsInBpY2tlbCIsInN0dW1wZiIsImvDpHNlIiwibW9sY2giLCJrb2hsIiwiZ251YmJlbCIsInNhY2siLCJoYW5zZWwiLCJwdWxsZXIiLCJhbHB0cmF1bSIsImthc3RlbiIsImtvcGYiLCJiZXV0ZWwiLCJiZXdvaG5lciIsImt1Y2hlbiIsImZyZXVuZCIsIm5hc2NoZXIiLCJvcGEiLCJyb3R6Iiwia2x1bXBlbiIsInBldGVyIiwiaGFuc2VsIiwiYmVuZ2VsIiwia29sbGVnZSIsImZsZWNrIiwibMO2ZmZlbCIsImx1cmNoIiwiaG9iZWwiLCJzcGF0ZW4iLCJwdWRlbCIsInJldHRpY2giLCJyaW5uc3RlaW4iLCJ1bmZhbGwiLCJsYXBwZW4iLCJrw7xiZWwiLCJtb3BzIiwicGZvc3RlbiIsInp3ZXJnIiwicHVkZGluZyIsIm51Y2tlbCIsInB1dHplciIsImzDvG1tZWwiLCJiYXJvbiIsIm1vcCIsImJlc2VuIiwiZmV1ZGVsIiwiYm9semVuIiwicGlseiIsInN0aWVmZWwiLCJrw7Z0ZXIiLCJndWxsaSIsInBmcm9wZiIsInNjaHJhbmsiLCJrw7ZuaWciLCJwb3R0IiwicGFkZGVsIiwicmlubnN0ZWluIiwiemlua2VuIiwiaGFrZW4iLCJ3aXR6IiwiYnVja2VsIiwia25lY2h0IiwiZmFuIiwic2NobWFuZCIsImtsb3BzIiwiZ2F1bmVyIiwibHVsbGkiLCJncmF1cGUiLCJwaW1wZiIsImthc3BlciIsInNwcm9zcyIsInRldWZlbCIsImhhbW1lbCIsImJvY2siLCJzY2htb2RkZXIiLCJwcsO8Z2VsIiwic3BpZXNzZXIiLCJhYWwiLCJncm9zY2hlbiIsImdlaXN0Iiwicm9jaGVuIiwia25vY2hlbiIsImhvcnN0IiwicXVhcmsiLCJrZWtzIiwiemF1c2VsIiwiaWx0aXMiLCJqZWNrIiwiaG9uayIsInNwYXJnZWwiLCJuaXBwZWwiLCJhdHplIiwibXVmZmVsIiwiZ3JlaXMiLCJwaW7DtmtlbCIsImdlaGlsZmUiLCJoYWx1bmtlIiwibGF1Y2giLCJ0aMO2bGUiLCJvbmtlbCIsImtsZWNrcyIsInNjaGFkZW4iLCJhdXN3dXJmIiwiaGVycGVzIiwidW5yYXQiLCJhYmtsYXRzY2giLCJmbGVnZWwiLCJnbG90emVyIiwic3TDtnBzZWwiLCJyZXN0IiwidmVyc3VjaCIsImtvbXBvc3QiLCJmbHVjaCIsImpvZ3VydCIsInDDtm1wZWwiLCJzdGllbCIsImZldHplbiIsImR1c2NoZXIiLCJnbm9tIiwic2NobHVjayIsInNjaG51cGZlbiIsImluZmVrdCIsImluZmFya3QiLCJnZXJ1Y2giLCJyYW1ibyIsImRhY2tlbCIsInNjaHdpbmdlbCIsImRpZWIiLCJmbGFkZW4iLCJmbGF0c2NoZW4iLCJmdXNzZWwiLCJrbmlsY2giLCJmcm9zY2giLCJ3b21iYXQiLCJhbmZhbGwiLCJob2hsc2F1bSIsImJpbWJhbSIsIndvZGthIiwiZHVmdCIsImthZGF2ZXIiLCJiZWZhbGwiLCJlZ2VsIiwiZsOkbmdlciJdOw0KdmFyIGFfd29ydGxpc3RlNSA9IFsic2VrcmV0IiwiYmFsZyIsImJsYWciLCJtb25zdGVyIiwiZ2Vsw7Z0IiwiaW1pdGF0Iiwic2tlbGV0dCIsImRpbmciLCJ1bmRpbmciLCJhdWdlIiwiYnJvdCIsImRlbyIsImluc2VrdCIsImJpZXIiLCJtdXMiLCJlbmRlIiwiZnV0dGVyIiwiZ2V3w6RjaHMiLCJwcm9kdWt0IiwiZ2Vyw7ZsbCIsImJvbmJvbiIsImZ1cnVua2VsIiwicGFrZXQiLCJ2aXJ1cyIsImRlc2FzdGVyIiwic3TDvGNrIiwiZmFzcyIsInpldWciLCJmZXJrZWwiLCJlaSIsImdld2l0dGVyIiwiaG9ybW9uIiwiZXhwZXJpbWVudCIsImd1bGFzY2giLCJzY2huaXR6ZWwiLCJmZWxsIiwidGhlYXRlciIsInNjaGF1c3BpZWwiLCJiYWJ5Iiwic3BpZWx6ZXVnIiwiZ2VsIiwiZG9udXRsb2NoIiwiZ2VsZWUiLCJnZWx1bXBlIiwic2NoYWYiLCJtb2xla8O8bCIsImdld8O8cnoiLCJnZXNwZW5zdCIsImdlc3Bpbm5zdCIsIm1pdHRlbCIsImdlc2NobmV0eiIsIm9yZ2FuIiwicmlzb3R0byIsInZpZWgiLCJnZXPDpHNzIiwiZ2V6w7xjaHQiLCJla3plbSIsIm1vcGVkIiwiZ2Vyw7xtcGVsIiwiaGlybiIsImdlZsOkc3MiLCJ3YWNoc3R1bSIsIm1vbG9jaCIsInJpbm5zYWFsIiwiZ2VtZW5nZSIsIm9wb3NzdW0iLCJmcmV0dGNoZW4iLCJow6RobmNoZW4iLCJwbGFua3RvbiIsInVudGllciIsInVuZ2V0w7xtIiwiZ2VicsOkdSIsImZvbmR1ZSIsImJlaXNwaWVsIiwiZWxlbmQiLCJsZWlkIiwiZ2lmdCIsInZlcmRlcmJlbiIsInVuZ2zDvGNrIiwiZHJhbWEiLCJ0cmF1bWEiLCJ2ZXJzYWdlbiIsImZpYXNrbyIsImRpbGVtbWEiLCJkZWJha2VsIiwidGFidSIsImdlcsO8Y2h0IiwiaGluZGVybmlzIiwiZGluZ2RvbmciLCJkaW5nc2J1bXMiLCJnZXdpY2h0IiwiYWJ3YXNzZXIiLCJhYmJpbGQiLCJtb2RlbGwiLCJnZW3DpGxkZSIsImJyZXR0IiwiZ2ViYWxsZXIiLCJnZW3DpGNodCIsInRvdXBldCIsImdlc2Nod8OkdHoiLCJnZXJpcHBlIiwicGVjaCIsImxlaWRlbiIsInZlcmJyZWNoZW4iLCJmb3NzaWwiLCJzeW1wdG9tIiwiYmllc3QiLCJ3cmFjayIsImdlYsOkY2siLCJ1bmhlaWwiLCJ1bmdlbWFjaCIsIm9iamVrdCIsImdlc2ljaHQiLCJrb25mZWt0IiwiZ2VicmVjaGVuIiwibcOkcmNoZW4iLCJnZXLDpHQiLCJ2ZXJsdXN0Iiwic3luZHJvbSIsInN5bm9ueW0iLCJ3YXNzZXIiLCJ0aWVyIiwiZm9sbGlrZWwiLCJ1bmtyYXV0IiwidW5nZXppZWZlciIsImdldMO2c2UiLCJnZXNjaG1laXNzIiwiZ2Vicm9kZWwiLCJnZWpvZGVsIiwiaW5mZXJubyIsImdlcmljaHQiLCJtYWhsIiwia2FtZWwiLCJnZWJpc3MiLCJyZXB0aWwiLCJ2ZXJsaWVzcyIsInBhZGRlbCIsImdlYm90IiwibGFnZXIiLCJnZW1pc2NoIiwic2F1c2VuIiwiYW5nZWJvdCIsInppbW1lciIsIm3DtmJlbCIsInBhcmbDvG0iLCJwb2Rlc3QiLCJ1bmdlaGV1ZXIiLCJ6ZWljaGVuIiwidmVyc3RlY2siLCLDvGJlbCIsInNjcm90dW0iLCJlaXNlbiIsImJhbGxldHQiLCJsZWdvIiwiZ2VzZXR6IiwiZm9ybWF0IiwiYnVmZmV0IiwiZ3JhbnVsYXQiLCJkZXJpdmF0Il07DQogDQoNCi8vIFRlaWwgMjogRXJzdGVzIFdvcnQgZXJtaXR0ZWxuDQp2YXIgc19zY2hpbXBmd29ydCA9ICIiOw0KdmFyIGlfenVmYWxsc3phaGwgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBhX3dvcnRsaXN0ZTEubGVuZ3RoKTsNCnNfc2NoaW1wZndvcnQgPSBhX3dvcnRsaXN0ZTFbaV96dWZhbGxzemFobF07DQovLyBHZW51cyBlcm1pdHRlbG4gLSBmZW1pbmluLCBtYXNrdWxpbiBvZGVyIE5ldXRydW0NCmlfZ2VudXMgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAzKTsNCi8vY29uc29sZS53YXJuKGlfZ2VudXMpOw0Kc3dpdGNoIChpX2dlbnVzKSB7DQogICAgY2FzZSAwOg0KICAgICAgICBzX3NjaGltcGZ3b3J0ID0gc19zY2hpbXBmd29ydCArICIgIjsNCiAgICAgICAgYnJlYWs7DQogICAgY2FzZSAxOg0KICAgICAgICBzX3NjaGltcGZ3b3J0ID0gc19zY2hpbXBmd29ydCArICJyICI7DQogICAgICAgIGJyZWFrOw0KICAgIGNhc2UgMjoNCiAgICAgICAgc19zY2hpbXBmd29ydCA9IHNfc2NoaW1wZndvcnQgKyAicyAiOw0KICAgICAgICBicmVhazsNCiAgICBkZWZhdWx0Og0KICAgICAgICBjb25zb2xlLndhcm4oIkdlbnVzIGZhbHNjaGVyIFdlcnQ6IiArIGlfZ2VudXMpOw0KfQ0KDQovLyBUZWlsIDM6IFp3ZWl0ZXMgV29ydCBlcm1pdHRlbG4NCmlfenVmYWxsc3phaGwgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBhX3dvcnRsaXN0ZTIubGVuZ3RoKSAtIDE7DQpzX3NjaGltcGZ3b3J0ID0gc19zY2hpbXBmd29ydCArIGFfd29ydGxpc3RlMltpX3p1ZmFsbHN6YWhsXTsNCg0KLy8gVGVpbCA0OiAydGVyIFRlaWwgZGVzIDJ0ZW4gV29ydGVzIGVybWl0dGVsbg0Kc3dpdGNoIChpX2dlbnVzKSB7DQogICAgY2FzZSAwOg0KICAgICAgICBpX3p1ZmFsbHN6YWhsID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYV93b3J0bGlzdGUzLmxlbmd0aCkgLSAxOw0KICAgICAgICBzX3NjaGltcGZ3b3J0ID0gc19zY2hpbXBmd29ydCArIGFfd29ydGxpc3RlM1tpX3p1ZmFsbHN6YWhsXTsNCiAgICAgICAgYnJlYWs7DQogICAgY2FzZSAxOg0KICAgICAgICBpX3p1ZmFsbHN6YWhsID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYV93b3J0bGlzdGU0Lmxlbmd0aCkgLSAxOw0KICAgICAgICBzX3NjaGltcGZ3b3J0ID0gc19zY2hpbXBmd29ydCArIGFfd29ydGxpc3RlNFtpX3p1ZmFsbHN6YWhsXTsNCiAgICAgICAgYnJlYWs7DQogICAgY2FzZSAyOg0KICAgICAgICBpX3p1ZmFsbHN6YWhsID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYV93b3J0bGlzdGU1Lmxlbmd0aCkgLSAxOw0KICAgICAgICBzX3NjaGltcGZ3b3J0ID0gc19zY2hpbXBmd29ydCArIGFfd29ydGxpc3RlNVtpX3p1ZmFsbHN6YWhsXTsNCiAgICAgICAgYnJlYWs7DQogICAgZGVmYXVsdDoNCiAgICAgICAgY29uc29sZS53YXJuKCJHZW51cyBmYWxzY2hlciBXZXJ0OiIgKyBpX2dlbnVzKTsNCn0NCg0KDQoNCnJldHVybiBzX3NjaGltcGZ3b3J0Ow==</field>
        <comment pinned="false" h="80" w="160">Beschreibe diese Funktion …</comment>
      </block>
      

      Die Funktion liefert immer genau einen Ausdruck zurück.
      Viel Spaß damit, euer Einarmiges Scherzdebakel


      Update 1:
      Hier eine Version die 1x die Minute ein neues Schimpfwort nach

      0_userdata.0.Schimpfwortgenerator.Schimpfwort
      
      <block xmlns="https://developers.google.com/blockly/xml" type="procedures_defcustomreturn" id="h!J2T(,rRS$uRe+#Tw8y" x="38" y="-337">
        <mutation statements="false"></mutation>
        <field name="NAME">Schimpfwortgenerator</field>
        <field name="SCRIPT">Ly8gRnJlaSBuYWNoIGh0dHBzOi8vZ2l0aHViLmNvbS9OaWtvbGFpUmFka2UvU2NoaW1wZm9saW5vL3dpa2kNCg0KLy8gVGVpbCAxOiBXb3J0bGlzdGVuIGRlZmluaWVyZW4NCnZhciBhX3dvcnRsaXN0ZTEgPSBbIkR1bXBmZSIsIlN0YXViaWdlIiwiTWllZmVuZGUiLCJTdGlua2VuZGUiLCJHYW1tbGlnZSIsIkhpbmtlbmRlIiwiV2luemlnZSIsIlBvcGVsaWdlIiwiTmFzc2UiLCJGdXJ6ZW5kZSIsIlJvc3RpZ2UiLCJIb2hsZSIsIlNpZmZpZ2UiLCJNaWVzZSIsIktydW1tZSIsIktsYXBwcmlnZSIsIlRyb2NrZW5lIiwiSGFhcmlnZSIsIlVyYWx0ZSIsIkdydW56ZW5kZSIsIlNjaHJlaWVuZGUiLCJNZWNrZXJuZGUiLCJOZXJ2ZW5kZSIsIlNhYmJlcm5kZSIsIlRyaWVmZW5kZSIsIk1vZHJpZ2UiLCJMdW1waWdlIiwiTGF1c2lnZSIsIlNpbm5sb3NlIiwiT2xsZSIsIlVubsO2dGlnZSIsIkRhbXBmZW5kZSIsIkxlZHJpZ2UiLCJFaW5hcm1pZ2UiLCJMZWVyZSIsIkzDpHN0aWdlIiwiSGV1bGVuZGUiLCJQaWNrZWxpZ2UiLCJGYXVsZSIsIlJhbnppZ2UiLCJUcsO8YmUiLCJEcmFsbGUiLCJCbGFua2UiLCJHaWVyaWdlIiwiVHJhbmlnZSIsIldhY2tlbG5kZSIsIlRvcmtlbG5kZSIsIlfDvHN0ZSIsIkZpc2NoaWdlIiwiQmVrbmFja3RlIiwiVmVya29ya3N0ZSIsIkhlaW1saWNoZSIsIkzDtmNocmlnZSIsIkJyb2NraWdlIiwiUGx1bXBlIiwiVGF0dHJpZ2UiLCJSYXR0ZXJuZGUiLCJTY2htdXR6aWdlIiwiTGlkZXJsaWNoZSIsIkTDtnNpZ2UiLCJQcm9sbGlnZSIsIkZpZXNlIiwiTXVmZmlnZSIsIk3DvGZmZWxuZGUiLCJQZWlubGljaGUiLCJOw7ZyZ2VsbmRlIiwiRmV0dGlnZSIsIlphaG5sb3NlIiwiRnJlY2hlIiwiU2Now6RiaWdlIiwiUGllZmlnZSIsIkd1bW1pZ2UiLCJMYWJicmlnZSIsIlBhdHppZ2UiLCJQZWx6aWdlIiwiUmV1ZGlnZSIsIlBla2lnZSIsIk3DvHJiZSIsIkhhcnppZ2UiLCJMYWhtZSIsIk1pY2tyaWdlIiwiQnLDpHNpZ2UiLCJab3R0ZWxpZ2UiLCJHZWxibGljaGUiLCJLbm9ycmlnZSIsIlNhbHppZ2UiLCJTY2hyaWxsZSIsIkR1c3NlbGlnZSIsIldpbmRpZ2UiLCJHcmF1c2lnZSIsIkdyw6Rzc2xpY2hlIiwiR3JvYmUiLCJTcGFja2lnZSIsIkthdXppZ2UiLCJGbGFjaHNpZ2UiLCJGcmFuc2lnZSIsIk1vdHppZ2UiLCJLYWhsZSIsIk5pZWRyaWdlIiwiS2VpZmVuZGUiLCJOaWNodGlnZSIsIkRyw7ZnZSIsIkZhZGUiLCJXZWluZW5kZSIsIkhpYmJlbGlnZSIsIlBsb2NraWdlIiwiQnJlbm5lbmRlIiwiRMO8cnJlIiwiS29jaGVuZGUiLCJLbmFyemVuZGUiLCJGYWx0aWdlIiwiU2NobGFtbWlnZSIsIkJyw7Zja2VsaWdlIiwiUmlzc2lnZSIsIlZlcmtlaW10ZSIsIkthbnRpZ2UiLCJHZWtsYXV0ZSIsIlF1aWVja2VuZGUiLCJGYXNlbG5kZSIsIkJlaXNzZW5kZSIsIkdlaMO2cm50ZSIsIlZlcmdlc3NlbmUiLCJCbGVpY2hlIiwiWndlaWNrZW5kZSIsIkZyb3N0aWdlIiwiTmFja2lnZSIsIkdydXNlbGlnZSIsIk1pbmRlcmUiLCJIYWdlcmUiLCJNYWdlcmUiLCJTY2h1cHBpZ2UiLCJCZWxlZ3RlIiwiU3TDpG5rZXJuZGUiLCJCw7ZzYXJ0aWdlIiwiUm9sbGVuZGUiLCJTY2hlY2tpZ2UiLCJSdWJiZWxuZGUiLCJTY2hpZWxlbmRlIiwiVHJhdHNjaGlnZSIsIkdyb3Rlc2tlIiwiQWJzdXJkZSIsIk1laGxpZ2UiLCJQbGF0dGUiLCJNw7xkZSIsIlRvdGFsZSIsIkJla2xvcHB0ZSIsIlNjaGF1cmlnZSIsIlRhdWJlIiwiQmV0w6R1YnRlIiwiQmVow6RtbWVydGUiLCJCZWxhbmdsb3NlIiwiQmVsZWlkaWd0ZSIsIkJldHJ1bmtlbmUiLCJCaXphcnJlIiwiRGlmZnVzZSJdOw0KdmFyIGFfd29ydGxpc3RlMiA9IFsiU3RhbXBmIiwiV2FiYmVsIiwiUHVwcyIsIlNjaG1hbHoiLCJTY2htaWVyIiwiSGFjayIsIlplbWVudCIsIlNwdWNrIiwiU3RhY2hlbCIsIktlbGxlciIsIkxhYmVyIiwiU3RvY2siLCJSdW56ZWwiLCJTY2hydW1wZiIsIkVrZWwiLCJTY2hub2RkZXIiLCJNYXRzY2giLCJXdXJtIiwiRWl0ZXIiLCJTcGVjayIsIk1pc3QiLCJLbG90eiIsIlfDvHJnIiwiTHVtcGVuIiwiU2NobGVpbSIsIld1cnN0IiwiRG9vZiIsIkJyYXQiLCJTY2h3YW1tIiwiS3JhdHoiLCJHcm90dGVuIiwiS3JpZWNoIiwiR2lmdCIsIlNjaGxhYmJlciIsIkfDtmJlbCIsIktsZWIiLCJTY2htYWRkZXIiLCJHcmluZCIsIkxhYmJlciIsIkx1ZnQiLCJNYXNzZW4iLCJTY2hpbW1lbCIsIk1pbmkiLCJPY2hzZW4iLCJQcm9ibGVtIiwiUXVhc3NlbCIsIlNjaG5hcHMiLCJTYWZ0IiwiRnJpZW1lbCIsIlphcHBlbCIsIlRyb3BmIiwiUGx1bnRzY2giLCJTdW1wZiIsIkhlY2tlbiIsIkdyYWIiLCJTY2h3aXR6IiwiU2NobmFyY2giLCJTY2hsZWljaCIsIlNjaGx1ZmYiLCJGbMO2dGVuIiwiSG9seiIsIktyZWlzY2giLCJEdWxsaSIsIkx1c2NoZW4iLCJHYW1tZWwiLCJBbHTDtmwiLCJSw7ZjaGVsIiwiR2xpYmJlciIsIkxhY2giLCJLcmFjaCIsIktuaWNrIiwiUXVldHNjaCIsIlF1YXRzY2giLCJRdWlldHNjaCIsIktuYXV0c2NoIiwiVMO8bXBlbCIsIlRlaWNoIiwiS25hdHRlciIsIlNhdWYiLCJQaXBpIiwiU3RydWxsZXIiLCJHcsOkdGVuIiwiTmFzZW4iLCJQZWNoIiwiTGVpZXIiLCJSZWllciIsIkJsw7ZkIiwiU2Nob3JmIiwiU2FiYmVsIiwiUXVlbmdlbCIsIkJhbmFuZW4iLCJVbnNpbm5zIiwiUGx1bnNjaCIsIkZydXN0IiwiTG90dGVyIiwiRnVtbWVsIiwiQmx1YmJlciIsIldvYmJlbCIsIlZvbGxiYXJ0IiwiTGFjayIsIktsbyIsIk1vZGVyIiwiS25pcnNjaCIsIlppdHRlciIsIkthbHQiLCJTY2hsw7xyZiIsIlNjaG5pZWYiLCJLbGVja2VyIiwiUnVtYmEiLCJTY2h3dXJiZWwiLCJTY2hyYWJiZWwiLCJTY2hsYXVjaCIsIlNjaHJ1bXBlbCIsIkjDvGhuZXIiLCJTY2hsYWNrZXIiLCJCcmFiYmVsIiwiS3JhbXBmIiwiUHLDvGdlbCIsIlJhcHBlbCIsIlp1cHBlbCIsIlBsdW5kZXIiLCJEb25uZXIiLCJSaWVzZW4iLCJCdXR0ZXIiLCJXaXNjaHdhc2NoIiwiUG9sdGVyIiwiVHJhbXBlbCIsIlNhdWVyIiwiSGFtcGVsIiwiQml0dGVyIiwiTWFzc2VsIiwiRmxpdHoiLCJXYXJtIiwiU2NobGluZyIsIlBsdW1wcyIsIlF1w6RsIiwiU3RyYW1wZWwiLCJTY2hsZWNrIiwiUmVjeWNsaW5nIiwiRWdhbCIsIkJsZWNoIiwiSG9ycm9yIiwiUnVtcGVsIiwiU2NobnVsbGVyIiwiU2NoZXJ6IiwiTmFja3QiLCJQYW1wZWwiLCJNb3Jhc3QiLCJGbGFjaCIsIkFuZ3N0IiwiU3BlaSIsIlB1bXBlbCIsIkF1c3NjaGxhZyIsIlF1YWxtIiwiUmFtYmF6YW1iYSIsIktsZWluIiwiU3BydWRlbCJdOw0KdmFyIGFfd29ydGxpc3RlMyA9IFsic3VwcGUiLCJzb2NrZSIsImJvbWJlIiwiYm91bGV0dGUiLCJzY2h3YXJ0ZSIsIndhcnplIiwiYmV1bGUiLCJwZXN0IiwicGZsYXVtZSIsInLDvGJlIiwiZ2VpZ2UiLCJyYXR0ZSIsImtyYW5raGVpdCIsInd1bmRlIiwib21hIiwic3R1bGxlIiwibGllc2UiLCJicnV0IiwiaGVubmUiLCJ6d2llYmVsIiwiYnVkZSIsImtpc3RlIiwiYnJhdXQiLCJsZXVjaHRlIiwia3LDtnRlIiwibnVzcyIsInNwaW5uZSIsImdydWJlIiwidG9pbGV0dGUiLCJrcmFrZSIsInBmw7x0emUiLCJiYWNrZSIsImJyYXRzY2hlIiwia2xhdHNjaGUiLCJudWRlbCIsImtub2xsZSIsInTDvHRlIiwibmFzZSIsIm1hZGUiLCJ0b25uZSIsImtyYW1wZSIsImLDvHJzdGUiLCJ3aW5kZWwiLCJzZW1tZWwiLCJoYXhlIiwiZ3LDpGZpbiIsInNjaGxldWRlciIsInppZXJkZSIsImtyw6RoZSIsImxhdHRlIiwibmlldGUiLCJyYXNzZWwiLCJhc3NlbCIsInRvcnRlIiwiZ2FsbGUiLCJsYXRzY2hlIiwic2NocnVsbGUiLCJrYW5vbmUiLCJibGFzZSIsInBlbGxlIiwidHJpbmUiLCJxdWVlbiIsInplY2tlIiwicHJhbGluZSIsIm1hZ3QiLCJwcmFjaHQiLCJmcml0dGUiLCJzb3NzZSIsImxhcnZlIiwibXVybWVsIiwiaGV4ZSIsInBhbXBlIiwic2lyZW5lIiwiZHLDvHNlIiwia2xldHRlIiwicGV0emUiLCJicnVtbWUiLCJnbGF0emUiLCJxdWFsbGUiLCJuYXR0ZXIiLCJrcmFsbGUiLCJ6aWVnZSIsImdyw7x0emUiLCJzw7xsemUiLCJudWxwZSIsIndhbXBlIiwiZnJpa2FkZWxsZSIsImZsdW5kZXIiLCJ0cnVsbGEiLCJ6aWNodGUiLCJ1c2NoaSIsImt1aCIsInBhcHBlIiwiaHVwZSIsInRyw7Z0ZSIsInNjaGFiZSIsImthbmFsbGllIiwic2NoYXJ0ZSIsInJpbGxlIiwiYW1zZWwiLCJhbGdlIiwibMO8Y2tlIiwiYnJlbXNlIiwibcO8Y2tlIiwiYsO8cnN0ZSIsIndhbm5lIiwicG9ja2UiLCJwbMO2cnJlIiwic2NoYWJyYWNrZSIsInd1cHBlIiwic2ljaGVsIiwidGFudGUiLCJyZXVzZSIsInJhdHNjaGUiLCJwYXVrZSIsImZsdXBwZSIsIm1hdHJvbmUiLCJodW1tZWwiLCJwYXJhZGUiLCJhdHRyYXBwZSIsImzDvGdlIiwiZmxvc3NlIiwiZnVuemVsIiwiZ3Vya2UiLCJwaWVwZSIsImfDtnJlIiwia29sYmVuIiwic2FtbWx1bmciLCJwcmltZWwiLCJvbW1lIiwibG90dGUiLCJ1bmtlIiwic3RyaXBwZSIsInNlaWZlIiwicGzDtnR6ZSIsIndlc3BlIiwibGF3aW5lIiwidGFibGV0dGUiLCJrcsO8Y2tlIiwiZ3JhemllIiwiZGl2YSIsInB1bGxlIiwibmVzc2VsIiwia2FrZXJsYWtlIiwiZGlzdGVsIiwiYW3DtmJlIiwiZmFja2VsIiwiaMO8ZnRlIiwicnVpbmUiLCJ3YWNodGVsIiwic2V1Y2hlIiwia2lwcGUiLCJzY2hpcHBlIiwiZ2VzdGFsdCIsIndvbGtlIiwibXVtaWUiLCJzcHVyIiwiY3JlbWUiLCJtb3R0ZSJdOw0KdmFyIGFfd29ydGxpc3RlNCA9IFsiYnVzY2giLCJmaW5rIiwibmFnZWwiLCJiYW1tZWwiLCJrbG9wcGVyIiwidGVudGFrZWwiLCJicsOkZ2VuIiwic2NobHVtcGYiLCJodXN0ZW4iLCJlcnNhdHoiLCJoYXVmZW4iLCJrbsO2ZGVsIiwicsO8c3NlbCIsImhpbnRlcm4iLCJlaW1lciIsInBpY2tlbCIsInN0dW1wZiIsImvDpHNlIiwibW9sY2giLCJrb2hsIiwiZ251YmJlbCIsInNhY2siLCJoYW5zZWwiLCJwdWxsZXIiLCJhbHB0cmF1bSIsImthc3RlbiIsImtvcGYiLCJiZXV0ZWwiLCJiZXdvaG5lciIsImt1Y2hlbiIsImZyZXVuZCIsIm5hc2NoZXIiLCJvcGEiLCJyb3R6Iiwia2x1bXBlbiIsInBldGVyIiwiaGFuc2VsIiwiYmVuZ2VsIiwia29sbGVnZSIsImZsZWNrIiwibMO2ZmZlbCIsImx1cmNoIiwiaG9iZWwiLCJzcGF0ZW4iLCJwdWRlbCIsInJldHRpY2giLCJyaW5uc3RlaW4iLCJ1bmZhbGwiLCJsYXBwZW4iLCJrw7xiZWwiLCJtb3BzIiwicGZvc3RlbiIsInp3ZXJnIiwicHVkZGluZyIsIm51Y2tlbCIsInB1dHplciIsImzDvG1tZWwiLCJiYXJvbiIsIm1vcCIsImJlc2VuIiwiZmV1ZGVsIiwiYm9semVuIiwicGlseiIsInN0aWVmZWwiLCJrw7Z0ZXIiLCJndWxsaSIsInBmcm9wZiIsInNjaHJhbmsiLCJrw7ZuaWciLCJwb3R0IiwicGFkZGVsIiwicmlubnN0ZWluIiwiemlua2VuIiwiaGFrZW4iLCJ3aXR6IiwiYnVja2VsIiwia25lY2h0IiwiZmFuIiwic2NobWFuZCIsImtsb3BzIiwiZ2F1bmVyIiwibHVsbGkiLCJncmF1cGUiLCJwaW1wZiIsImthc3BlciIsInNwcm9zcyIsInRldWZlbCIsImhhbW1lbCIsImJvY2siLCJzY2htb2RkZXIiLCJwcsO8Z2VsIiwic3BpZXNzZXIiLCJhYWwiLCJncm9zY2hlbiIsImdlaXN0Iiwicm9jaGVuIiwia25vY2hlbiIsImhvcnN0IiwicXVhcmsiLCJrZWtzIiwiemF1c2VsIiwiaWx0aXMiLCJqZWNrIiwiaG9uayIsInNwYXJnZWwiLCJuaXBwZWwiLCJhdHplIiwibXVmZmVsIiwiZ3JlaXMiLCJwaW7DtmtlbCIsImdlaGlsZmUiLCJoYWx1bmtlIiwibGF1Y2giLCJ0aMO2bGUiLCJvbmtlbCIsImtsZWNrcyIsInNjaGFkZW4iLCJhdXN3dXJmIiwiaGVycGVzIiwidW5yYXQiLCJhYmtsYXRzY2giLCJmbGVnZWwiLCJnbG90emVyIiwic3TDtnBzZWwiLCJyZXN0IiwidmVyc3VjaCIsImtvbXBvc3QiLCJmbHVjaCIsImpvZ3VydCIsInDDtm1wZWwiLCJzdGllbCIsImZldHplbiIsImR1c2NoZXIiLCJnbm9tIiwic2NobHVjayIsInNjaG51cGZlbiIsImluZmVrdCIsImluZmFya3QiLCJnZXJ1Y2giLCJyYW1ibyIsImRhY2tlbCIsInNjaHdpbmdlbCIsImRpZWIiLCJmbGFkZW4iLCJmbGF0c2NoZW4iLCJmdXNzZWwiLCJrbmlsY2giLCJmcm9zY2giLCJ3b21iYXQiLCJhbmZhbGwiLCJob2hsc2F1bSIsImJpbWJhbSIsIndvZGthIiwiZHVmdCIsImthZGF2ZXIiLCJiZWZhbGwiLCJlZ2VsIiwiZsOkbmdlciJdOw0KdmFyIGFfd29ydGxpc3RlNSA9IFsic2VrcmV0IiwiYmFsZyIsImJsYWciLCJtb25zdGVyIiwiZ2Vsw7Z0IiwiaW1pdGF0Iiwic2tlbGV0dCIsImRpbmciLCJ1bmRpbmciLCJhdWdlIiwiYnJvdCIsImRlbyIsImluc2VrdCIsImJpZXIiLCJtdXMiLCJlbmRlIiwiZnV0dGVyIiwiZ2V3w6RjaHMiLCJwcm9kdWt0IiwiZ2Vyw7ZsbCIsImJvbmJvbiIsImZ1cnVua2VsIiwicGFrZXQiLCJ2aXJ1cyIsImRlc2FzdGVyIiwic3TDvGNrIiwiZmFzcyIsInpldWciLCJmZXJrZWwiLCJlaSIsImdld2l0dGVyIiwiaG9ybW9uIiwiZXhwZXJpbWVudCIsImd1bGFzY2giLCJzY2huaXR6ZWwiLCJmZWxsIiwidGhlYXRlciIsInNjaGF1c3BpZWwiLCJiYWJ5Iiwic3BpZWx6ZXVnIiwiZ2VsIiwiZG9udXRsb2NoIiwiZ2VsZWUiLCJnZWx1bXBlIiwic2NoYWYiLCJtb2xla8O8bCIsImdld8O8cnoiLCJnZXNwZW5zdCIsImdlc3Bpbm5zdCIsIm1pdHRlbCIsImdlc2NobmV0eiIsIm9yZ2FuIiwicmlzb3R0byIsInZpZWgiLCJnZXPDpHNzIiwiZ2V6w7xjaHQiLCJla3plbSIsIm1vcGVkIiwiZ2Vyw7xtcGVsIiwiaGlybiIsImdlZsOkc3MiLCJ3YWNoc3R1bSIsIm1vbG9jaCIsInJpbm5zYWFsIiwiZ2VtZW5nZSIsIm9wb3NzdW0iLCJmcmV0dGNoZW4iLCJow6RobmNoZW4iLCJwbGFua3RvbiIsInVudGllciIsInVuZ2V0w7xtIiwiZ2VicsOkdSIsImZvbmR1ZSIsImJlaXNwaWVsIiwiZWxlbmQiLCJsZWlkIiwiZ2lmdCIsInZlcmRlcmJlbiIsInVuZ2zDvGNrIiwiZHJhbWEiLCJ0cmF1bWEiLCJ2ZXJzYWdlbiIsImZpYXNrbyIsImRpbGVtbWEiLCJkZWJha2VsIiwidGFidSIsImdlcsO8Y2h0IiwiaGluZGVybmlzIiwiZGluZ2RvbmciLCJkaW5nc2J1bXMiLCJnZXdpY2h0IiwiYWJ3YXNzZXIiLCJhYmJpbGQiLCJtb2RlbGwiLCJnZW3DpGxkZSIsImJyZXR0IiwiZ2ViYWxsZXIiLCJnZW3DpGNodCIsInRvdXBldCIsImdlc2Nod8OkdHoiLCJnZXJpcHBlIiwicGVjaCIsImxlaWRlbiIsInZlcmJyZWNoZW4iLCJmb3NzaWwiLCJzeW1wdG9tIiwiYmllc3QiLCJ3cmFjayIsImdlYsOkY2siLCJ1bmhlaWwiLCJ1bmdlbWFjaCIsIm9iamVrdCIsImdlc2ljaHQiLCJrb25mZWt0IiwiZ2VicmVjaGVuIiwibcOkcmNoZW4iLCJnZXLDpHQiLCJ2ZXJsdXN0Iiwic3luZHJvbSIsInN5bm9ueW0iLCJ3YXNzZXIiLCJ0aWVyIiwiZm9sbGlrZWwiLCJ1bmtyYXV0IiwidW5nZXppZWZlciIsImdldMO2c2UiLCJnZXNjaG1laXNzIiwiZ2Vicm9kZWwiLCJnZWpvZGVsIiwiaW5mZXJubyIsImdlcmljaHQiLCJtYWhsIiwia2FtZWwiLCJnZWJpc3MiLCJyZXB0aWwiLCJ2ZXJsaWVzcyIsInBhZGRlbCIsImdlYm90IiwibGFnZXIiLCJnZW1pc2NoIiwic2F1c2VuIiwiYW5nZWJvdCIsInppbW1lciIsIm3DtmJlbCIsInBhcmbDvG0iLCJwb2Rlc3QiLCJ1bmdlaGV1ZXIiLCJ6ZWljaGVuIiwidmVyc3RlY2siLCLDvGJlbCIsInNjcm90dW0iLCJlaXNlbiIsImJhbGxldHQiLCJsZWdvIiwiZ2VzZXR6IiwiZm9ybWF0IiwiYnVmZmV0IiwiZ3JhbnVsYXQiLCJkZXJpdmF0Il07DQogDQovLyBUZWlsIDI6IEVyc3RlcyBXb3J0IGVybWl0dGVsbg0KdmFyIHNfc2NoaW1wZndvcnQgPSAiIjsNCnZhciBpX3p1ZmFsbHN6YWhsID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYV93b3J0bGlzdGUxLmxlbmd0aCk7DQpzX3NjaGltcGZ3b3J0ID0gYV93b3J0bGlzdGUxW2lfenVmYWxsc3phaGxdOw0KLy8gR2VudXMgZXJtaXR0ZWxuIC0gZmVtaW5pbiwgbWFza3VsaW4gb2RlciBOZXV0cnVtDQppX2dlbnVzID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMyk7DQovL2NvbnNvbGUud2FybihpX2dlbnVzKTsNCnN3aXRjaCAoaV9nZW51cykgew0KICAgIGNhc2UgMDoNCiAgICAgICAgc19zY2hpbXBmd29ydCA9IHNfc2NoaW1wZndvcnQgKyAiICI7DQogICAgICAgIGJyZWFrOw0KICAgIGNhc2UgMToNCiAgICAgICAgc19zY2hpbXBmd29ydCA9IHNfc2NoaW1wZndvcnQgKyAiciAiOw0KICAgICAgICBicmVhazsNCiAgICBjYXNlIDI6DQogICAgICAgIHNfc2NoaW1wZndvcnQgPSBzX3NjaGltcGZ3b3J0ICsgInMgIjsNCiAgICAgICAgYnJlYWs7DQogICAgZGVmYXVsdDoNCiAgICAgICAgY29uc29sZS53YXJuKCJHZW51cyBmYWxzY2hlciBXZXJ0OiIgKyBpX2dlbnVzKTsNCn0NCg0KLy8gVGVpbCAzOiBad2VpdGVzIFdvcnQgZXJtaXR0ZWxuDQppX3p1ZmFsbHN6YWhsID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYV93b3J0bGlzdGUyLmxlbmd0aCkgLSAxOw0Kc19zY2hpbXBmd29ydCA9IHNfc2NoaW1wZndvcnQgKyBhX3dvcnRsaXN0ZTJbaV96dWZhbGxzemFobF07DQoNCi8vIFRlaWwgNDogMnRlciBUZWlsIGRlcyAydGVuIFdvcnRlcyBlcm1pdHRlbG4NCnN3aXRjaCAoaV9nZW51cykgew0KICAgIGNhc2UgMDoNCiAgICAgICAgaV96dWZhbGxzemFobCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGFfd29ydGxpc3RlMy5sZW5ndGgpIC0gMTsNCiAgICAgICAgc19zY2hpbXBmd29ydCA9IHNfc2NoaW1wZndvcnQgKyBhX3dvcnRsaXN0ZTNbaV96dWZhbGxzemFobF07DQogICAgICAgIGJyZWFrOw0KICAgIGNhc2UgMToNCiAgICAgICAgaV96dWZhbGxzemFobCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGFfd29ydGxpc3RlNC5sZW5ndGgpIC0gMTsNCiAgICAgICAgc19zY2hpbXBmd29ydCA9IHNfc2NoaW1wZndvcnQgKyBhX3dvcnRsaXN0ZTRbaV96dWZhbGxzemFobF07DQogICAgICAgIGJyZWFrOw0KICAgIGNhc2UgMjoNCiAgICAgICAgaV96dWZhbGxzemFobCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGFfd29ydGxpc3RlNS5sZW5ndGgpIC0gMTsNCiAgICAgICAgc19zY2hpbXBmd29ydCA9IHNfc2NoaW1wZndvcnQgKyBhX3dvcnRsaXN0ZTVbaV96dWZhbGxzemFobF07DQogICAgICAgIGJyZWFrOw0KICAgIGRlZmF1bHQ6DQogICAgICAgIGNvbnNvbGUud2FybigiR2VudXMgZmFsc2NoZXIgV2VydDoiICsgaV9nZW51cyk7DQp9DQoNCg0KDQpyZXR1cm4gc19zY2hpbXBmd29ydDs=</field>
        <comment pinned="false" h="80" w="160">Beschreibe diese Funktion …</comment>
      </block>
      

      Edit: Hatte den Datenpunkt schreibgeschützt erstellt aber dann unbestätigt geschrieben - Skript korrigiert (gibt sonst Fehlermeldung im Log)

      posted in Skripten / Logik
      BananaJoe
      BananaJoe
    • RE: Strom sparen mit Fully Browser und Samsung Tablet

      @heinzie sagte in Strom sparen mit Fully Browser und Samsung Tablet:

      Was mir aber nicht so gefällt es der relativ hohe Stromverbrauch. Dazu mal ein paar Fragen:

      Definiere das doch mal, über wie viele Wh / kWh sprechen wir?

      Prinzipiell sind solche Geräte schon - im Verhältnis zu dem was diese tun - schon sparsam. Mit schnellen und langsamen Kernen. Und das Apps automatisch beendet oder in den Schlafmodus geschickt werden.

      Nun ist ein Tablet als Anzeige und die Software dazu genau das Gegenteil. In der Regel ist das Display einer der größten Stromfresser und der Fully muss alle Möglichkeiten und Tricks anwenden damit er eben nicht beendet oder in den Sleep geschickt wird. Schließlich soll der ständig lauschen und auf Befehle von außerhalb reagieren.

      Deshalb muss man einen Tod sterben. Und bevor man da nun am Stromverbrauch des Tablets herumschraubt: Wieviel verbraucht es denn so am Tag? Ohne Optimierungen, macht aber alles was es soll?

      Ich habe mehrere Amazon Fire-Tablets im Einsatz, ohne Sparmaßnahmen, Bildschirm immer an, volle Helligkeit, 24x7 in Betrieb.
      Eines verbraucht 3W im Dauerbetrieb, Energie gestern steht auf 0,057kWh.
      Ich zahle noch 40Cent pro kWh, pro Jahr verbraucht ein Tablet bei mir also 10,51 Euro wenn der Strom tatsächlich komplett bezogen würde, in der Realität dank Solar nicht mal die Hälfte.
      bei 30 Cent pro kWh wären es 7,88 Euro.

      Den Preis zahle ich für den Luxus das die Tablets alle ständig an sind, die aktuellen Werte anzeigen, sofort bedienbar sind. Und gleichzeitig das Nachtlicht 🙂

      posted in Off Topic
      BananaJoe
      BananaJoe
    • RE: iot Alexa Tutorial

      @nullo83 ich schreibe das gleiche wie @SwissMen , nur auf anderen Weg:

      Der IoT-Adapter kann beliebige Datenpunkte als Alexa-Gerät (über den ioBroker-Skill) bereitstellen.
      Den IoT-Adapter sowie den Skill unter Alexa hast du ja schon eingerichtet - prima.

      Unter Instanzen => iot.0 => Einstellungen kommst du in die Konfiguration:
      94134e17-6f13-4e72-8b70-af7177deb240-image.png

      Da gibt es den Reiter "Intelligente Aufzählungen" - alles was du dort siehst sind vermutlich die Geräte die du schon in Alexa hast / die Alexa schon gefunden hat. Ich nutze das nicht und habe dort alles deaktiviert:
      21734cb8-f590-4bba-bd1e-4269795d55a9-image.png
      Was diese Aufzählungen sind und wie diese Funktionieren muss dir jemand anders Erklären. Richtig eingerichtet würden neue Geräte halt automatisch auftauchen. Da aber alles selber geskripted habem habe ich das alles deaktiviert.

      Interessant ist der Reiter Alexa-Geräte:
      61bd4c7a-ff7a-422e-8fdf-964735d56c6c-image.png
      Dort kannst du beliebige Datenpunkte verknüpfen.
      Steckdosen und Lampen in der Regel als True/False Datenpunkt (an oder aus), der Datenpunkt kann aus einem Adapter stammen oder ein von dir erstellter sein (in der Regeln dann unterhalb von 0_userdata.0

      Ich nehme hier mal den folgenden:

      0_userdata.0.AlarmSystem.Global.active
      

      Du gehst oben auf den +, dann öffnet sich der Dialog wo du den Datenpunkt auswählen kannst:
      46c2c05c-2140-45c0-9d33-2368d5d1af67-image.png
      Bestätigen und einen Moment warten, es geht ein neues Fenster auf:
      239cdca7-308c-4751-abda-b8faa245dbc1-image.png

      Hier kannst du den Smart-Name angeben - unter dem Namen kannst du den später (gleich im Anschluss!) über Alexa ansprechen. Und den Typ, der ist unter anderem für das Symbol in Alexa notwendig und ob Alexa den als Lampe behandelt. Wenn du mit OK Speicherst siehts du wie der Eintrag entsteht und mit der Cloud synchronisiert wird. Der wird zunächst grün
      d680ece9-bfda-4d84-9a74-53bd016dde82-image.png
      und wenn das Grüne weg ist, ist es auch mit der Cloud synchronisiert. Jetzt kannst du Alexa nach neuen Geräten suchen lassen und er wird das Gerät finden.
      Schaltest du es per Alexa ein oder aus so wird der Datenpunkt auf True oder False / Wahr oder falsch gesetzt.
      Und das Geräte schaltet (Datenpunkt aus einem Adapter) oder dein Skript springt an (eigener Datenpunkt).

      Hat ein Gerät mehrere Eigenschaften, z.B. eine Lampe die man Ein-/Ausschalten kannst aber auch Dimmen (0 bis 100%), legst du die Lampe einfach 2x hier an, beide male unter dem exakt gleichen Namen, beide male als Lampe. Der True/False Datenpunkt muss dann aber POWER heißen, der Datenpunkt für die Helligkeit Dimmer. Er macht dann eine Gruppe daraus:
      389e06a6-79e4-482e-a455-6883e6444347-image.png

      Der IoT-Adapter schaltet nur. Den kannst du nicht nutzen um den Status abzufragen bzw. in Alexa wird er dir den Status auch nicht anzeigen können.

      Den Alexa-Adapter in ioBroker brauchst du nicht unbedingt dafür, den brauchst du wenn du Alexa von ioBroker aus steuern willst, z.B. um per Text ein Sprachkommando zu senden.

      Edit: Typos korrigiert

      posted in Cloud Dienste
      BananaJoe
      BananaJoe
    • RE: Akku ausschließlich über Netzstrom laden

      Es soll Menschen geben, die haben ein paar Pylontech-Akkus im Keller (oder LiFePO4 Selbstbau-Akkus), laden diese per 48V Ladegeräte die per Tasmota-Plugs ein und ausgeschaltet werden, oder besser noch mit einem (oder mehreren) Huawei R4850-G2 Netzteilen die per ESP8266 geregelt werden und dann genau soviel einspeisen wie der Hichi am Stromzähler oder Shelly 3EM als Überschuss ausweisen:

      • https://github.com/KlausLi/Esp-HuaweiR4850-Controller
      • https://www.youtube.com/watch?v=NC1X--fSeu0

      Und zum Einspeisen nimmt man 1 bis 3 SoyouSource Wechselrichter, die kann man auf Batteriebetrieb stellen. Es liegt eine Strommessklammer dabei mit welcher einer genau den Strom einer Phase ausgleichen kann.
      Alternativ steuert man die ebenfalls mit einem ESP8266 und dann wird genau soviel eingespeist wie der Hichi am Stromzähler oder Shelly 3EM als Verbrauch melden (und auf nahezu 0 geregelt)

      • https://github.com/KlausLi/Esp-Soyosource-Controller
      • https://www.youtube.com/watch?v=zpDsxDEU1P0

      Also ich habe gehört das manche das wohl so machen ...

      posted in Hardware
      BananaJoe
      BananaJoe
    • RE: [Vorlage] Schimpfwortgenerator

      Oh ha, jetzt bin ich berühmt ... dafür Blockly genutzt zu haben ...

      posted in Skripten / Logik
      BananaJoe
      BananaJoe
    • RE: Test Adapter Energiefluss v3.6.x GitHub/Latest

      @skb sagte in Test Adapter Energiefluss v2.0.x GitHub/Latest:

      @skb Ich habe die Idee nun einmal mehr verfolgt und bin inzwischen bei diesem Ergebnis angelangt und würde Euch um Eure Meinung bitten 🙂

      Und noch ein paar Tunnel, Gleise und einen Bahnhof bitte ... 😀

      posted in Tester
      BananaJoe
      BananaJoe
    • RE: [Skript] Absolute Feuchte berechnen

      Ich habe mal eine Version v0.6.6 erstellt.
      Diese kommt ohne das zusätzliche Modul dewpoint aus, man muss dieses als nicht mehr in der JavaScript-Instanz hinzufügen (ich hatte das vorhaben im Quellcode gesehen und dachte das kann doch nicht so schwer sein)

      //
      // Raumklima - v0.6.6
      //
      // Berechnet Taupunkt, absolute Luftfeuchtigkeit, Enthalpie, Lüftungsempfehlung,
      // gemessene Temperatur & Luftfeuchtigkeit inkl. Offset zwecks Kalibrierung
      // -----------------------------------------------------------------------------
      //
      // Formeln zur Berechnung der Luftfeuchtigkeit:
      // http://www.nabu-eibelshausen.de/Rechner/feuchte_luft_enthalpie.html
      //
      // Empfehlung Paul53:
      // Kalibrierung der Offsetwerte in einer für den Vergleich relevanten Umgebung
      // z.B. 22°C, 65% Luftfeuchte (nicht im Winter).
      //
      // gute Infos zum Raumklima:
      // https://www.energie-lexikon.info/luftfeuchtigkeit.html
      // http://www.energiebuero-online.de/bauphysik/richtigluften.htm
       
      // Autoren des Skripts:
      // -----------------------------------------------------------------------------
      // - Paul53:
      //   Formeln, Idee, Experte im Bereich Raumklima, Korrekturen am gr. Skript
      // - Solear:
      //   Zusammenfassung der Skripte/Formeln von Paul53
      // - ruhr70:
      //   Ein Skript für alle vorhandenen Räume
      // - eric 2905:
      //   Optimierungen, viele neue Ideen, JSON-Ausgabe, globale Datenpunkte
      // - Andy3268:
      //   Hinzufügen der 4.ten Bedingung für Raumfeuchte Grenzwerte
      // - BananaJoe:
      //   Verzicht auf externes Modul "dewpoint"
       
      // https://forum.iobroker.net/topic/2313/skript-absolute-feuchte-berechnen/437 
      // TODO:
      // -----------------------------------------------------------------------------
      //
      // - Einstellungen Hysterese (Expertenmodus)
      //
      // - setState / getState, die es nicht gibt: Fehler abfangen und Warnung ausgeben, damit der Adapter sich nicht beendet
      //
      // - Luftdruck alternativ vom Messgerät und nicht über Skript (ggf. per Raum)
      //
      // - Auswählbar: Datenpunkte ohne Einheit (zusätzlich) erzeugen (z.B. für vis justgage, value & indicator)
      //
      // - Auswählbar:
      //   Zweig Raum:    NICHT anlegen
      //   JSON:          NICHT anlegen
      //   DETAILS:       NICHT anlegen
      //   CONTROL:       NICHT anlegen
      //
      // - JSON wird recht groß: ggf. Datenpunkte für JSON auswählbar machen
      //
      // - ggf. JSON nicht als String zusammenbauen, sondern als json-Objekt (dann JSON.stringify(json))
      //
      // - Zähler einbauen: Anzahl Räume in Hysterese (Grenzbereich)
      //
      // # "Lüftungsengine":
      // -------------------
      // - möglichst an die individuellen Situationen und Vorlieben anpassbar
      // - differenziertere Lüftungsempfehlung
      // - CO2, Luftgüte einbeziehen
      // - Experteneinstellungen (welche Werte sind einem wichtig)
      // - Modus mit Werten/Prioritäten (wie dringend muss gelüftet werden)
      // - Kellerentlüftung einbauen (Raum markierbar als Keller)
      // - Sommer / Winter (Heizperiode) berücksichtigen
      // - dringend lüften, ab 70% rel. Luftfeuchtigkeit und geeigneter Außenluft (Vergl. absolute Luftfeuchtigkeit)
      // - Massnahme: zu trockene Luft (rel. Luftfeuchtigkeit < 40%)
      // - Massnahme: Luft rel. Feuch > 60% oder 65% (?)
      // - Feuchtigkeitstrend berücksichtigen. Ist ie Tendenz fallend, Bedingung "Entfeuchten" überstimmen.
       
      // Ideensammlung Lüftungsengine
      // - zentraler Datenpunkt: Heizperiode
      // - je Raum eine opt. Datenpunkt für eine zugeordnete Heizung (Zieltemperatur und Heizung an/aus)
      // - je Raum die Wunschtemperatur
      // - Prio: schlechte Luftqualität
      // - Prio: kühlen, wenn Temperaturunterschied zu groß
      // - Prio: zu trockene Luft (rel.)
      // - Prio: zu feuchte Luft (rel.)
       
      // berücksichtigen / Beobachtungen:
      //
      // wenn draussen zu kalt ist, macht das lüften tlw. keinen Sinn mehr
      // wenn die Zimmertemperatur bis zum Minimum abkühlt kann torz Unterschid xi/xa
      // xi und die rel. Luftfeuchte weiter steigen, da die dann kältere Raumluft weniger 
      // Luftfeuchtigkeittragen kann.
       
      // -----------------------------------------------------------------------------
      // Einstellungen Skriptverhalten, eigene Parameter -  !! bitte anpassen !!
      // -----------------------------------------------------------------------------
       
      // Wichtig:                             // betrifft den CONTROL Zweig bei den Raumdatepunkten (Offsets, Raummindestemperatur (Auskühlschutz))
      var skriptConf  = true;                 // Anwender kann sich aussuchen, ob er die Werte im Skript oder über die Objekte pflegen möchte
                                             // true:  Raumwerte werden über das Skript geändert/überschrieben (var raeume)
                                             // false: Raumwerte werden über Objekte (z.B. im Admin, Zustände oder VIS) geändert
       
      var debug = false;                      // true: erweitertes Logging einschalten
       
       
      // eigene Parameter:
      var hunn            = 15;           // eigene Höhe über nn (normalnull), z.B. über http://de.mygeoposition.com zu ermitteln
      var defaultTemp     = 18.00;     // Default TEMP_Minimum, wenn im Raum nicht angegeben (Auskühlschutz, tiefer soll eine Raumtemperatur durchs lüften nicht sinken)
      var defaultMinFeu   = 40.00;     // Default Mindest Feuchte wenn nicht angegeben.
      var defaultMaxFeu   = 60.00;     // Default Maximal Feuchte wenn nicht angegeben.
       
      var cronStr         = "*/30 * * * *";       // Zeit, in der alle Räume aktualisiert werden (da auf Änderung der Sensoren aktualisiert wird, kann die Zeit sehr hoch sein)
      var strDatum        = "DD-MM-JJJJ SS:mm:ss";// Format, in dem das Aktualisierungsdatum für das JSON ausgegeben wird
       
       
       
      // ### Experteneinstellungen ###
       
      // Lüftungsengine
       
      var hysMinTemp      = 0.5;              // Default 0.5, Hysterese Mindesttemperatur (Auskühlschutz). Innerhalb dieser Deltatemperatur bleibt die alte Lüftungsempfehlung für den Auskühlschutz bestehen.
      var hysEntfeuchten  = 0.2;              // Default 0.3, Hysterese Entfeuhten: Delta g/kG absolute Luftfeuchte. In dem Delta findet keine Änderung der alten Lüftungsempfehlung statt    
       
       
      // Skriptverhalten
      var delayRooms      = 500;              // Zeit in ms als Verzögerung, wie die Räume abgearbeitet werden
       
       
      // Pfade für die Datenpunkte:
      var pfad        = "Raumklima"   +".";   // Pfad unter dem die Datenpunkte in der Javascript-Instanz angelegt werden
       
      // Unterpfade unterhalb des Hauptpfads
      var raumPfad    = "Raum"        +".";   // Pfad unterhalb des Hauptpfads für die Räume
      var controlPfad = "CONTROL"     +".";   // Pfad innerhalb des Raums für Kontrollparameter
      var detailPfad  = "DETAILS"     +".";   // Pfad innerhalb des Raums für Detailparameter ("" und ohne ".", wenn kein Detailpfad gewünscht)
      var detailEnginePfad = "DETAILS_Lüftungsempfehlung" + "."; // Pfad innerhalb des Raums für Detailparameter zur Lüftungsengine
       
      var infoPfad    = "Skriptinfos" +".";   // Pfad für globale Skriptparameter zur Info
       
       
      // -----------------------------------------------------------------------------
      // Räume mit Sensoren, Parametrisierung -           !! bitte anpassen !!
      // -----------------------------------------------------------------------------
       
      // jeder Sensor darf nur einmal verwendet werden!
       
      // wird kein Aussensensor angegeben, wird der Sensor als Aussensensor behandelt!
       
      var raeume = { // Keine Leerzeichen (Name wird als Datenpunktname verwendet!)
          // Sensoren Aussen
          "TF_Haustuer" : {
              "Sensor_TEMP"           :   'zigbee.0.xxx1.temperature'/*Aussensensor Haustuer Temperatur */,
              "Sensor_HUM"            :   'zigbee.0.xxx1.humidity'/*Aussensensor Haustuer Feuchtigkeit */,
              "Sensor_TEMP_OFFSET"    :   0.0,
              "Sensor_HUM_OFFSET"     :   0
                     
          },
          "TF_Terrasse" : {
              "Sensor_TEMP"           :   'zigbee.0.xxx2.temperature'/*Aussensensor Garten Temperatur */,
              "Sensor_HUM"            :   'zigbee.0.xxx2.humidity'/*Aussensensor Garten Feuchtigkeit */,
              "Sensor_TEMP_OFFSET"    :   0.0,
              "Sensor_HUM_OFFSET"     :   0
                     
          },
          // Sensoren Innen
          "Badezimmer" : {
              "Sensor_TEMP"           :   'zigbee.0.xxx3.temperature'/* Sensor Badezimmer Temperatur */,
              "Sensor_HUM"            :   'zigbee.0.xxx3.humidity'/* Sensor Badezimmer Feuchtigkeit */,
              "Sensor_TEMP_OFFSET"    :   0.0,
              "Sensor_HUM_OFFSET"     :   0,
              "TEMP_Minimum"          :   defaultTemp, // oder Zieltemperatur in Form von: 20.00 angeben
              "Aussensensor"          :   "TF_Haustuer"
          },
          "Schlafzimmer" : {
              "Sensor_TEMP"           :   'zigbee.0.xxx4.temperature',
              "Sensor_HUM"            :   'zigbee.0.xxx4.humidity',
              "Sensor_TEMP_OFFSET"    :   0.0,
              "Sensor_HUM_OFFSET"     :   0,
              "TEMP_Minimum"          :   defaultTemp, // oder Zieltemperatur in Form von: 20.00 angeben
              "Aussensensor"          :   "TF_Terrasse"
          },
          "Wohnzimmer" : {
              "Sensor_TEMP"           :   'zigbee.0.xxx5.temperature',
              "Sensor_HUM"            :   'zigbee.0.xxx5.humidity',
              "Sensor_TEMP_OFFSET"    :   0.0,
              "Sensor_HUM_OFFSET"     :   0,
              "TEMP_Minimum"          :   defaultTemp, // oder Zieltemperatur in Form von: 20.00 angeben
              "Aussensensor"          :   "TF_Terrasse"
          },
         
      };
       
       
      // =============================================================================
       
      // =============================================================================
      // Skriptbereich. Ab hier muss nichts mehr eingestellt / verändert werden.
      // =============================================================================
       
      // =============================================================================
      
      // Das Modul dewpoint - integriert, keine externe Abhängigkeit mehr
      // Start Modul Dewpoint
      // Calculation of absolute humidity x (in g water per kg dry air) and of dew point temperature (in �C)
      var dewpoint = function(h) {
              var z = 1.0 - (0.0065 / 288.15) * h;
              // air pressure in hPa
              this.p = 1013.25 * Math.pow(z, 5.255);
              this.A = 6.112;
              }
      dewpoint.prototype.Calc = function(t, rh) {
              t = parseFloat(t);
              var m = 17.62;
              var Tn = 243.12;
              if (t < 0.0) {
              m = 22.46;
              Tn = 272.62;
              }
       
              var     sd = this.A * Math.exp(m * t / (Tn + t));
              var d = sd * rh / 100.0;
       
          return {
             x: 621.98 * d /(this.p - d),
             dp: Tn * Math.log(d/this.A) / (m - Math.log(d/this.A))
              };
      };
      // Ende Modul Dewpoint
      
       
      var idSkriptinfoBar         = pfad + infoPfad + "Luftdruck";
      var idSkriptinfoHunn        = pfad + infoPfad + "Höhe_über_NN";
       
      // forceCreation = true, damit bei geändert eigener Höhe im Konfigurationsbereich der Datenpunkt neu geschrieben wird
      createState(idSkriptinfoBar, luftdruck(hunn), true, {
         name: 'mittlerer Luftdruck in bar',
         desc: 'mittlerer Luftdruck in bar, errechnet anhand der eigenen Höhe über NN',
         type: 'number',
         unit: 'bar',
         role: 'info'
      });
       
      createState(idSkriptinfoHunn, hunn, true, {
         name: 'Eigene Höhe über NN',
         desc: 'Eigene Höhe über NN (Normal Null), als Basis für den mittleren Luftdruck',
         type: 'number',
         unit: 'm',
         role: 'info'
      });
       
       
      var raumDatenpunkte = {
         "x" : {
             "DpName" : "Feuchtegehalt_Absolut",
             "init": 0,
             "dp": {
                 "name": 'absoluter Feuchtegehalt',
                 "desc": 'absoluter Feuchtegehalt, errechnet',
                 "type": 'number',
                 "role": 'value',
                 "unit": 'g/kg'
             }
         },
         "rh" : {
             "DpName" : "relative_Luftfeuchtigkeit",
             "init": 0,
             "dp": {
                 "name": 'gemessene relative Luftfeuchtigkeit (inkl. Offset)',
                 "desc": 'relative Luftfeuchtigkeit, vom Sensor + Offset zum Ausgleich von Messungenauigkeiten des Geräts',
                 "type": 'number',
                 "role": 'value',
                 "unit": '%'
             }
         },
         "dp" : {
             "DpName" : "Taupunkt",
             "init": 0,
             "dp": {
                 "name": 'Taupunkt',
                 "desc": 'Taupunkt. Temperatur von Wänden, Fenstern, usw. ab der sich die Feuchtigkeit niederschlägt.',
                 "type": 'number',
                 "role": 'value',
                 "unit": '°C'
             }
         },
         "t" : {
             "DpName" : "Temperatur",
             "init": 0,
             "dp": {
                 "name": 'gemessene Temperatur (inkl. Offset)',
                 "desc": 'gemessene Temperatur vom Sensor zzgl. eines Offsets um Geräteungenauigkeiten auszugleichen',
                 "type": 'number',
                 "role": 'value',
                 "unit": '°C'
             }
         },
         "h" : {
             "DpName" : detailPfad + "Enthalpie",
             "init": 0,
             "dp": {
                 "name": 'Enthalpie',
                 "desc": 'Enthalpie',
                 "type": 'number',
                 "role": 'value',
                 "unit": 'kJ/kg'
             }
         },
         "sdd" : {
             "DpName" : detailPfad +"Sättigungsdampfdruck",
             "init": 0,
             "dp": {
                 "name": 'Sättigungsdampfdruck',
                 "desc": 'Sättigungsdampfdruck',
                 "type": 'number',
                 "role": 'value',
                 "unit": 'hPa'
             }
         },
         "dd" : {
             "DpName" : detailPfad + "Dampfdruck",
             "init": 0,
             "dp": {
                 "name": 'Dampfdruck',
                 "desc": 'Dampfdruck',
                 "type": 'number',
                 "role": 'value',
                 "unit": 'hPa'
             }
         },
         "rd" : {
             "DpName" : "Dampfgewicht",
             "init": 0,
             "dp": {
                 "name": 'Dampfgewicht (Wassergehalt)',
                 "desc": 'Dampfgewicht (Wassergehalt)',
                 "type": 'number',
                 "role": 'value',
                 "unit": 'g/m³'
             }
         },
         "maxrd" : {
             "DpName" : detailPfad + "Dampfgewicht_maximal",
             "init": 0,
             "dp": {
                 "name": 'max. Dampfgewicht (Wassergehalt)',
                 "desc": 'max. Dampfgewicht (Wassergehalt) bei aktueller Temperatur',
                 "type": 'number',
                 "role": 'value',
                 "unit": 'g/m³'
             }
         },
         "lüften" : {
             "DpName" : "Lüftungsempfehlung",
             //"init": false,
             "dp": {
                 "name": 'Lüftungsempfehlung',
                 "desc": 'Lüftungsempfehlung',
                 "type": 'boolean',
                 "role": 'value'
             }
         },
         "lüften_b1" : {
             "DpName" : detailEnginePfad + "Lüften_b1_Entfeuchten",
             //"init": false,
             "dp": {
                 "name": 'Lüften Bedingung 1 entfeuchten',
                 "desc": 'Lüften Bedingung 1 entfeuchten erfüllt',
                 "type": 'boolean',
                 "role": 'value'
             }
         },
         "lüften_b2" : {
             "DpName" : detailEnginePfad + "Lüften_b2_Kühlen",
             //"init": false,
             "dp": {
                 "name": 'Lüften Bedingung 2 kühlen',
                 "desc": 'Lüften Bedingung 2 kühlen erfüllt',
                 "type": 'boolean',
                 "role": 'value'
             }
         },
         "lüften_b3" : {
             "DpName" : detailEnginePfad + "Lüften_b3_Auskühlschutz",
             //"init": false,
             "dp": {
                 "name": 'Lüften Bedingung 3 Auskühlschutz',
                 "desc": 'Lüften Bedingung 3 Auskühlschutz erfüllt (Innentemperatur soll nicht unter Minimumteperatur fallen)',
                 "type": 'boolean',
                 "role": 'value'
             }
         },
         "lüften_b4" : {
             "DpName" : detailEnginePfad + "Lüften_b4_Raumfeuchte",
             //"init": false,
             "dp": {
                 "name": 'Lüften Bedingung 4 Raumfeuchte',
                 "desc": 'Lüften Bedingung 4 Raumfeuchte erfüllt',
                 "type": 'boolean',
                 "role": 'value'
             }
         },
         "lüften_Hysterese" : {
             "DpName" : detailEnginePfad + "Lüften_Hysterese",
             //"init": false,
             "dp": {
                 "name": 'Logik im Bereich der Hysterese. Keine Änderung der bestehenden Lüftungsempfehlung.',
                 "desc": 'Logik im Bereich der Hysterese. Keine Änderung der bestehenden Lüftungsempfehlung.',
                 "type": 'boolean',
                 "role": 'value'
             }
         },
         "lüften_Beschreibung" : {
             "DpName" : detailEnginePfad + "Lüftungsempfehlung_Beschreibung",
             "init": "",
             "dp": {
                 "name": 'Lüftungsempfehlung beschreibender Text',
                 "desc": 'Lüftungsempfehlung beschreibender Text',
                 "type": 'string',
                 "role": 'value'
             }
         }
      };
       
         // #1 - Entfeuchten:    Außenluft ist mind. (hysEntfeuchten + 0,1) trockener als Innen
         // #2 - Kühlen:         Außentemperatur ist mindestens 0,6 Grad kühler als innen TODO: im Winter auch?
         // #3 - Auskühlschutz:  Innentemperatur ist höher als die Mindesttemperatur
       
       
      var raumControl = {
         "Sensor_TEMP_OFFSET" : {
             "DpName" : "Sensor_TEMP_OFFSET",
             "init": 0,
             "dp": {
                 "name": 'Offset Temperatur zum Sensormesswert (Ausgleich von Ungenauigkeiten)',
                 "desc": 'Offset Temperatur zum Sensormesswert (Ausgleich von Ungenauigkeiten)',
                 "type": 'number',
                 "role": 'control.value',
                 "unit": '°C'
             }
         },
         "Sensor_HUM_OFFSET" : {
             "DpName" : "Sensor_HUM_OFFSET",
             "init": 0,
             "dp": {
                 "name": 'Offset Luftfeuchtigkeit zum Sensormesswert (Ausgleich von Ungenauigkeiten)',
                 "desc": 'Offset Luftfeuchtigkeit zum Sensormesswert (Ausgleich von Ungenauigkeiten)',
                 "type": 'number',
                 "role": 'control.value',
                 "unit": '%'
             }
         },
         "TEMP_Minimum" : {
             "DpName" : "TEMP_Minimum",
             "init": 0,
             "dp": {
                 "name": 'Auskühlschutz Mindestraumtemperatur',
                 "desc": 'Auskühlschutz Mindestraumtemperatur zum lüften',
                 "type": 'number',
                 "role": 'control.value',
                 "unit": '°C'
             }
         },
         "FEUCH_Minimum" : {
             "DpName" : "FEUCH_Minimum",
             "init": 0,
             "dp": {
                 "name": 'Mindest Rel. Raumfeuchte',
                 "desc": 'Mindest Rel. Raumfeuchte zum lüften',
                 "type": 'number',
                 "role": 'control.value',
                 "unit": '%'
             }
         },
         "FEUCH_Maximum" : {
             "DpName" : "FEUCH_Maximum",
             "init": 0,
             "dp": {
                 "name": 'Maximal Rel. Raumfeuchte ',
                 "desc": 'Maximal Rel. Raumfeuchte zum lüften',
                 "type": 'number',
                 "role": 'control.value',
                 "unit": '%'
             }
         },
         "Aussensensor" : {
             "DpName" : "Aussensensor",
             "init": "",
             "dp": {
                 "name": 'Aussensensor, der zum Vergleich genommen wird',
                 "desc": 'Aussensensor, der zum Vergleich genommen wird',
                 "type": 'string',
                 "role": 'control.value'
             }
         }
      };
       
       
      // globale Skript-Variablen/Objekte
      //------------------------------------------------------------------------------
       
      var xdp     = new dewpoint(hunn);
       
      var pbar    = luftdruck(hunn);          // individueller Luftdruck      in bar (eigene Höhe)
       
       
       
      //------------------------------------------------------------------------------
      // Funktionen
      //------------------------------------------------------------------------------
       
      function writeJson(json) {
         return JSON.stringify(json);
      }
       
       
      // prüft ob setObjects() für die Instanz zur Verfügung steht (true/false)
      function checkEnableSetObject() { 
         var enableSetObject = getObject("system.adapter.javascript." + instance).native.enableSetObject;
         return enableSetObject;
      }
       
       
      function setChannelName(channelId,channelName){
         if(checkEnableSetObject()) { // wenn setObject nicht in der Instanz freigeschaltet ist, wird der Channel nicht angelegt
         // CHANNEL anlegen
             setObject("javascript." + instance + "." + channelId, {
                 common: {
                     name: channelName
                 },
                 type: 'channel'
             }, function(err) {
                 if (err) logs('Cannot write object: ' + err,"error");
             });
         }
      }
       
       
      function lueftenDp(datenpunktID) {
         return (datenpunktID == "lüften") || (datenpunktID == "lüften_Beschreibung") || (datenpunktID == "lüften_b1") || (datenpunktID == "lüften_b2") || (datenpunktID == "lüften_b3") || (datenpunktID == "lüften_b4") || (datenpunktID ==  "lüften_Hysterese");
      }
       
       
      function createDp() {
         var name;
         var init;
         var forceCreation;
         var common;
         for (var raum in raeume) {
             for (var datenpunktID in raumDatenpunkte) {
                 name = pfad + raumPfad + raum + "." + raumDatenpunkte[datenpunktID].DpName;
                 init = raumDatenpunkte[datenpunktID].init;
                 forceCreation = false; // Init der Datenpunkte wird nur beim ersten Star angelegt. Danach bleiben die Wert auch nach Skritpstart enthalten.
                 common = raumDatenpunkte[datenpunktID].dp;
                 
                 if (lueftenDp(datenpunktID)) {
                     if (!raeume[raum].Aussensensor) {
                         if (datenpunktID == "lüften") {
                             log(raum + ": kein Aussensensor angegeben.  ### Messpunkte werden als Aussensensoren behandelt. ###","info"); // Warnung ist im Log OK, wenn es sich um einen Außensensor handelt.
                             setChannelName(pfad + raumPfad + raum,"Aussensensor");
                         }
                     } else {
                         createState(name, init , forceCreation, common);
                         if (debug) log("neuer Datenpunkt: " + name);
                     }
                 } else {
                     createState(name, init , forceCreation, common);
                     if (debug) log("neuer Datenpunkt: " + name);
                 }
                 
             }
             for (var control in raumControl) {
                 name = pfad + raumPfad + raum + "." + controlPfad + raumControl[control].DpName;
                 //init = raumControl[control].init;
                 forceCreation = skriptConf;
                 common = raumControl[control].dp;
                 if (typeof raeume[raum][raumControl[control].DpName] !=="undefined") {
                     init = raeume[raum][raumControl[control].DpName];
                     createState(name, init , forceCreation, common);
                     var channelname = "Nur Info. Werte aus dem Skript zählen. Kann im Skript umgestellt werden.";
                     if (!skriptConf) channelname = "Änderungen hier in den Objekten werden berechnet";
                     setChannelName(pfad + raumPfad + raum + "." + controlPfad.substr(0, controlPfad.length-1),channelname);
                 }
             }
         }
         
         //eric2905 Datenpunkt "Lüften" erzeugen
         // -------------------------------------------------------------------------
         createState(pfad + 'Lüften', false, {
          name: 'Muss irgendwo gelüftet werden',
          desc: 'Muss irgendwo gelüftet werden',
          type: 'boolean',
          unit: '',
          role: 'value'
         });
       
         createState(pfad + 'Lüften_Liste', "[]", {
          name: 'Liste der Räume in denen gelüftet werden muss',
          desc: 'Liste der Räume in denen gelüftet werden muss',
          type: 'string',
          unit: '',
          role: 'value'
         });
       
         // eric2905 Ende -----------------------------------------------------------
       
         //eric2905 Datenpunkt "JSON" erzeugen
         // -------------------------------------------------------------------------
         createState(pfad + 'JSON', "", {
          name: 'JSON-Ausgabe aller Werte',
          desc: 'JSON-Ausgabe aller Werte',
          type: 'string',
          unit: '',
          role: 'value'
         });
         // eric2905 Ende -----------------------------------------------------------
       
         //eric2905 Datenpunkt "Aktualsierung" erzeugen
         // -------------------------------------------------------------------------
         createState(pfad + 'Aktualsierung', "", {
          name: 'Aktualisierungszeitpunkt der JSON-Ausgabe',
          desc: 'Aktualisierungszeitpunkt der JSON-Ausgabe',
          type: 'string',
          unit: '',
          role: 'value'
         });
         // eric2905 Ende -----------------------------------------------------------
        
        
         //eric2905 Datenpunkt "countLueften" erzeugen
         // -------------------------------------------------------------------------
         createState(pfad + 'Lüften_Anzahl', 0, {
          name: 'Anzahl Lüftungsempfehlungen',
          desc: 'Anzahl Lüftungsempfehlungen',
          type: 'number',
          unit: '',
          role: 'value'
         });
         // eric2905 Ende -----------------------------------------------------------
       
         log("Datenpunkte angelegt");
      }
       
       
      // rundet einen Float auf eine bestimmte Anzahl Nachkommastellen
      function runden(wert,stellen) {
         return Math.round(wert * Math.pow(10,stellen)) / Math.pow(10,stellen);
      }
       
      // berechnet den mittleren Luftdruck für eine Höhenangabe in NN 
      function luftdruck(hunn) {
         var pnn         = 1013.25;                                  // Mittlerer Luftdruck          in hPa bei NN
         var p           = pnn - (hunn / 8.0);                       // individueller Luftdruck      in hPa (eigenen Höhe)
         return p / 1000;                                            // Luftdruck von hPa in bar umrechnen
      }
       
      // Color Boolean (farbige Ausgabe Boolean als String, z.B. für das Log)
      function cob(boolean) { 
         var cobStr = (boolean) ? '<span style="color:lime;"><b>true</b></span>' : '<span style="color:red;"><b>false</b></span>';
         return cobStr;
      }
       
      function makeNumber(wert) {
         if(isNaN(wert)) {
             wert = parseFloat(wert.match(/\d+[.|,]?\d+/g));
         }
         return wert;
      }
       
       
       
      // Berechnungen Luftwerte 
      // ----------------------
       
      function calcSaettigungsdampfdruck(t) {    // benötigt die aktuelle Temperatur
         // Quelle: http://www.wetterochs.de/wetter/feuchte.html#f1
         var sdd,a,b;
         a = 7.5;
         b = 237.3;
         sdd = 6.1078 * Math.pow(10,((a*t)/(b+t)));
         return sdd; // ssd = Sättigungsdampfdruck in hPa
      }
       
      function calcDampfdruck(sdd,r) {
         // Quelle: http://www.wetterochs.de/wetter/feuchte.html#f1
         var dd = r/100 *sdd;
         return dd;  // dd = Dampfdruck in hPa
      }
       
      function calcTemperaturKelvin(t) {
         var tk = t + 273.15;
         return tk;
      }
       
      function calcDampfgewicht(dd,t) { // Wassergehalt
         // Dampfgewicht rd oder AF(r,TK) = 10^5 * mw/R* * DD(r,T)/TK
         // Quelle: http://www.wetterochs.de/wetter/feuchte.html#f1
         var tk = calcTemperaturKelvin(t);
         var mw = 18.016; // kg/kmol (Molekulargewicht des Wasserdampfes)
         var R  = 8314.3; // J/(kmol*K) (universelle Gaskonstante)
         var rd = Math.pow(10,5) * mw/R * dd/tk; 
         return rd; // rd = Dampfgewicht in g/m^3
      }
       
      function calcMaxDampfgewicht(rd,r) {
         var maxrd = rd / r *100;
         return maxrd;
      }
       
       
       
       
      // Berechnung: alle Werte je Raum
      // -------------------------------
       
       
      function calc(raum) {                                           // Über Modul Dewpoint absolute Feuchte berechnen
       
         var t           = getState(raeume[raum].Sensor_TEMP).val;   // Temperatur auslesen
         var rh          = getState(raeume[raum].Sensor_HUM).val;    // Feuchtigkeit relativ auslesen
       
         t   = makeNumber(t);                                        // Temperatur in Number umwandeln
         rh  = makeNumber(rh);                                       // relative Luftfeuchtigkeit in Number umwandeln
       
         var toffset     = 0.0;                                      // Default Offset in °C
         var rhoffset    = 0;                                        // Default Offset in %
         if(typeof raeume[raum].Sensor_TEMP_OFFSET !=="undefined") {
             // Temperatur, wenn ein Offset vorhanden ist, diesen auslesen und Default überschreiben
             var idtoffset = pfad + raumPfad+ raum + "." + controlPfad + "Sensor_TEMP_OFFSET";
             toffset = getState(idtoffset).val;  // Offset aus den Objekten/Datenpunkt auslesen
         }
         if(typeof raeume[raum].Sensor_HUM_OFFSET !=="undefined") {
             // Luftfeuchtigkeit, wenn ein Offset vorhanden ist, diesen auslesen und Default überschreiben
             var idrhoffset = pfad + raumPfad + raum + "." + controlPfad + "Sensor_HUM_OFFSET";
             rhoffset = getState(idrhoffset).val;  // Offset aus den Objekten/Datenpunkt auslesen
         }
       
         t       = t     + toffset;      // Messwertanpassung: gemessene Temperatur um den Offset ergänzen
         rh      = rh    + rhoffset;     // Messwertanpassung: gemessene relative Luftfeuchtigkeit um Offset ergänzen
       
         var y           = xdp.Calc(t, rh);
         var x   = y.x;  // Zu errechnende Variable für Feuchtegehalt in g/kg
         var dp  = y.dp; // Zu errechnende Variable für Taupunkt in °C
       
         var h       = 1.00545 * t + (2.500827 + 0.00185894 * t) * x;    // Enthalpie in kJ/kg berechnen
       
         var sdd     = calcSaettigungsdampfdruck(t);                     // Sättigungsdampfdruck in hPa
         var dd      = calcDampfdruck(sdd,rh);                           // dd = Dampfdruck in hPa
         var rd      = calcDampfgewicht(dd,t);                           // rd = Dampfgewicht/Wassergehalt in g/m^3
         var maxrd   = calcMaxDampfgewicht(rd,rh);                       // maximales Dampfgewicht in g/m^3
         
       
         var idx     = pfad + raumPfad + raum + "." + raumDatenpunkte["x"].DpName;   // DP-ID absolute Luftfeuchte in g/kg
         var iddp    = pfad + raumPfad + raum + "." + raumDatenpunkte["dp"].DpName;  // DP-ID Taupunkt in °C
         var idt     = pfad + raumPfad + raum + "." + raumDatenpunkte["t"].DpName;   // DP-ID Temperatur inkl. Offset
         var idrh    = pfad + raumPfad + raum + "." + raumDatenpunkte["rh"].DpName;  // DP-ID relative Luftfeuhtigkeit inkl. Offset
         var ih      = pfad + raumPfad + raum + "." + raumDatenpunkte["h"].DpName;   // DP-ID Enthalpie in kJ/kg
         var isdd    = pfad + raumPfad + raum + "." + raumDatenpunkte["sdd"].DpName;
         var idd     = pfad + raumPfad + raum + "." + raumDatenpunkte["dd"].DpName;
         var ird     = pfad + raumPfad + raum + "." + raumDatenpunkte["rd"].DpName;
         var imaxrd  = pfad + raumPfad + raum + "." + raumDatenpunkte["maxrd"].DpName;
       
       
         setState(idx    , runden(x,2));     // errechnete absolute Feuchte in Datenpunkt schreiben
         setState(iddp   , runden(dp,1));    // errechneter Taupunkt in Datenpunkt schreiben
         setState(idt    , parseFloat(t));   // Sensor Temperatur        inkl. Offset
         setState(idrh   , parseFloat(rh));   // Sensor Relative Feuchte  inkl. Offset
         setState(ih     , runden(h,2));     // Enthalpie in kJ/kg
         setState(isdd   , runden(sdd,2));
         setState(idd    , runden(dd,2));
         setState(ird    , runden(rd,2));
         setState(imaxrd , runden(maxrd,2));
       
       
         // Logik-Engine: Lüftungsempfehlung berechnen
         // -------------------------------------------------------------------------
         if (!raeume[raum].Aussensensor) {
             // kein Aussensensor, keine Lüftungsempfehlung
             if (debug) log("<b>------ " + raum + " ------- Aussen, keine Lüftungsempfehlung -----------</b>");
             return; 
         }
         
         var aussen;
         var idta, idxa;
         if(typeof raeume[raum].Aussensensor !=="undefined") {
             aussen = raeume[raum].Aussensensor; // aussen = "Raumname" des zugehörigen Aussensensors
             idta = pfad + raumPfad + aussen + "." + raumDatenpunkte["t"].DpName;    // DP-ID zugehöriger Aussensensor, Temperatur aussen
             idxa = pfad + raumPfad + aussen + "." + raumDatenpunkte["x"].DpName;    // DP-ID zugehöriger Aussensensor, Luftfeuchtigkeit aussen
         } else {
             return; // wenn es keinen zugehörigen Aussensensor gibt, Funktion beenden (dann muss kein Vergleich berechnet werden)
         }
       
         var ti = t;                     // Raumtemperatur in °C
         var xi = runden(x,2);           // Raumfeuchtegehalt in g/kg
         var ta = getState(idta).val;    // Aussentemperatur in °C
         var xa = getState(idxa).val;    // Aussenfeuchtegehalt in g/kg
         if (xa == 0) return;            // TODO: warum? hatte ich leider nciht dokumentiert (ruhr70)
       
         var mi = defaultTemp;           // Temperaturmindestwert auf Default (Auskühlschutz)
         var xh = defaultMaxFeu;         // Feuchtemaximalwert auf Default
         var xt = defaultMinFeu;         // Feuchteminimalwert auf Default
      	  
         //if(typeof raeume[raum].TEMP_Minimum !=="undefined") {
         if(typeof raeume[raum].TEMP_Minimum == "number") {
             mi = raeume[raum].TEMP_Minimum;
         }
         if(typeof raeume[raum].FEUCH_Maximum == "number") {
             xh = raeume[raum].FEUCH_Maximum;
         }
       
         if(typeof raeume[raum].FEUCH_Minimum == "number") {
             xt = raeume[raum].FEUCH_Minimum;
         }
         
         // Auskühlschutz,  hysMinTemp (Variable) Grad hysMinTemp Hysterese. Tiefer darf die Innentemperatur nicht sinken
         var mih = mi + hysMinTemp;      // Temperaturmindestwert hoch (Mindesttemperatur plus Hysterese)
         var mit = mi;                   // Temperaturmindestwert tief
       
         var idLueften       = pfad + raumPfad + raum + "." + raumDatenpunkte["lüften"].DpName;
         var idLueftenText   = pfad + raumPfad + raum + "." + raumDatenpunkte["lüften_Beschreibung"].DpName;
         var idLueftenB1     = pfad + raumPfad + raum + "." + raumDatenpunkte["lüften_b1"].DpName;
         var idLueftenB2     = pfad + raumPfad + raum + "." + raumDatenpunkte["lüften_b2"].DpName;
         var idLueftenB3     = pfad + raumPfad + raum + "." + raumDatenpunkte["lüften_b3"].DpName;
         var idLueftenB4     = pfad + raumPfad + raum + "." + raumDatenpunkte["lüften_b4"].DpName;
         var idLueftenHys    = pfad + raumPfad + raum + "." + raumDatenpunkte["lüften_Hysterese"].DpName;
       
         var lueftenText     = "";
       
       
       
         // Lüftungslogik
         // -------------
         // Lüftungsempfehlung steuern mit 0,3 g/kg und 0,5 K Hysterese
         // Bedigungen fürs lüften
         var b1lp = (xa <= (xi - (hysEntfeuchten + 0.1)))    ? true : false;   // Bedingnung 1 lüften positv (Außenluft ist mind. 0,4 trockener als Innen)
         var b2lp = (ta <= (ti - 0.6))                       ? true : false;   // Bedingnung 2 lüften positv (Außentemperatur ist mindestens 0,6 Grad kühler als innen)
         var b3lp = (ti >= mih)                              ? true : false;   // Bedingnung 3 lüften positv (Innentemperatur ist höher als die Minimumtemperatur + Hysterese)
         var b4lp = (rh >= xh)                               ? true : false;   // Bedingnung 4 lüften positv (Relative Raumfeuchte ist höher als die Maximalfeuchtewert)
       
         var b1lpText = "Entfeuchten:    Außenluft ist mind. 0,4 trockener als Innen";
         var b2lpText = "Kühlen:         Außentemperatur ist mindestens 0,6 Grad kühler als innen";
         var b3lpText = "Auskühlschutz:  Innentemperatur ist höher als die Mindesttemperatur";
         var b4lpText = "Raumfeuchte:    Raumfeuchte ist höher als der Maximalfeuchte";
       
         setState(idLueftenB1,b1lp);
         setState(idLueftenB2,b2lp);
         setState(idLueftenB3,b3lp);
         setState(idLueftenB4,b4lp);
       
         // Bedingungen gegen das Lüften
         var b1ln = (xa >= (xi - 0.1))   ? true : false;   // Bedingnung 1 lüften negativ (Außenluft ist zu feucht)
         var b2ln = (ta >= (ti - 0.1))   ? true : false;   // Bedingnung 2 lüften negativ (Außentemperatur zu warm)
         var b3ln = (ti <= mit)          ? true : false;   // Bedingnung 3 lüften negativ (Innentemperatur niedriger als Mindesttemperatur)
         var b4ln = (rh <= xt)           ? true : false;   // Bedingnung 4 lüften negativ (Relative Raumfeuchte ist niedriger als die Mindestfeuchte)
       
         var b1lnText = "Entfeuchten:    Außenluft ist zu feucht";
         var b2lnText = "Kühlen:         Außentemperatur zu warm";
         var b3lnText = "Auskühlschutz:  Innentemperatur niedriger als Mindestraumtemperatur";
         var b4lnText = "Raumfeuchte:    Raumfeuchte ist niedriger als der Mindestfeuchte";
       
         
         // Logik:
         //--------------------------------------------------------------------------
         if (b1lp && b2lp && b3lp && b4lp) {
             // Lüftungsempfehlung, alle bedingungenen erfüllt
             lueftenText = "Bedingungen für Entfeuchten, Kühlen und Auskühlschutz erfüllt.";
             setState(idLueften, true);
             setState(idLueftenHys,false);
       
             if (debug) log(raum + ': <span style="color:limegreen;"><b>Lüftungsempfehlung</b></span>');
       
         } else if (b1ln || b2ln || b3ln || b4ln) {
             // Fenster zu. Ein Ausschlusskriterium reicht für die Empfehlung "Fenster zu".
             lueftenText = "Fenster zu:<br>";
             if (b1ln) lueftenText += b1lnText + "<br>";
             if (b2ln) lueftenText += b2lnText + "<br>";
             if (b3ln) lueftenText += b3lnText + "<br>";
      	   if (b4ln) lueftenText += b4lnText + "<br>";
             setState(idLueften, false);
             setState(idLueftenHys,false);
             if (debug) log(raum + ': <span style="color:red;"><b>Empfehlung Fenster zu</b></span>');
         } else {
             // Hysterese. Keine Änderung der bisherigen Empfehlung.
             if (debug) log(raum + ': <span style="color:orange;"><b>im Bereich der Hysterese</b></span> (keine Änderung der Lüftungsempfehlung');
             if (getState(idLueften).val === null) setState(idLueften,false); // noch keine Empfehlung vorhanden, "Fenster zu" empfehlen
             lueftenText = "Hysterese, keine Änderung der Lüftungsempfehlung";
             setState(idLueftenHys,true);
         }
         setState(idLueftenText, lueftenText);
       
       
         /* Erklärung Lüftungslogik (von Paul53)
            Ergänzung #4 (von Andy3268)
         Lüften:
         wenn    abs. Aussenfeuchte  <   abs. Innenfeuchte     - Hysterese (Entfeuchten)
         UND     Aussentemperatur    <   Innentemperatur       - Hysterese (Kühlen)
         UND     Innentemperatur     >=  Raumtemperaturminimum + Hysterese (Auskühlschutz)
         UND     Innenfeuchte        >=  Raummaximalfechte
         */
       
         // lüften (und - Alle Bedingungen müssen erfüllt sein):
         // #1 - Entfeuchten:    Außenluft ist mind. (hysEntfeuchten + 0,1) trockener als Innen
         // #2 - Kühlen:         Außentemperatur ist mindestens 0,6 Grad kühler als innen TODO: im Winter auch?
         // #3 - Auskühlschutz:  Innentemperatur ist höher als die Mindesttemperatur
         // #4 - Raumfeuchte:    Innenfeuchte ist höher als die Maximalfeuchte
       
         // nicht lüften (oder):
         // #1 - Außenluft ist zu feucht
         // #2 - Außentemperatur zu warm
         // #3 - Innentemperatur niedriger als Mindestraumtemperatur
         // #4 - Innenfeuchte niedriger als Mindestfeuchte
       
         if (debug) log(raum + ":" + cob(b4ln) + " Raumluft ist trocken genug (b4ln): ");
         if (debug) log(raum + ":" + cob(b3ln) + " Außenluft ist zu feucht (b3ln): ");
         if (debug) log(raum + ":" + cob(b2ln) + " Außentemperatur zu warm (b2ln): ");
         if (debug) log(raum + ":" + cob(b1ln) + " Außenluft ist zu feucht (b1ln): " + ": xa: " + xa + " >= (xi - 0.1) " + (xi - 0.1));
         if (debug) log(raum + ": Fenster zu (ein true reicht):");
         
         //if (debug) log(raum + ": b1lp: " + b1lp+ ", b2lp: " + b2lp+ ", b3lp: " + b3lp, b4lp: " + b4lp);
         if (debug) log(raum + ":" + cob(b4lp) + " Raumfeuchte ist niedriger als der Mindstwert (b4lp): "); 
         if (debug) log(raum + ":" + cob(b3lp) + " Innentemperatur ist höher als die Mindesttemperatur (b3lp): ");
         if (debug) log(raum + ":" + cob(b2lp) + " Außentemperatur ist mindestens 0,6 Grad kühler als innen (b2lp): ");
         if (debug) log(raum + ":" + cob(b1lp) + " Außenluft ist mind. 0,4° trockener als Innen (b1lp):  xa: " + xa + " <= (xi - 0.4) " + (xi - 0.4));
         if (debug) log(raum + ": Lüftungsempfehlung (alle Bedingungen auf true):");
       
         if (debug) log(raum + ", ti:"+ti+", ta: "+ta+", xi:"+xi+", xa: "+xa+", mih:"+mih+", mit:"+mit,"info");
         if (debug) log("<b>------ " + raum + " ------- Aussensensor: " + aussen + " -----------</b>");
      }
       
       
       
       
       
      //eric2905 Erzeuge JSON und setzen Variablen "anyLueften" und "countLueften"
      // -----------------------------------------------------------------------------
      function createJSON() {
         // alle Daten im JSON werden als String abgelegt
         if (debug) log("=========================================================");
         if (debug) log("Erzeugung JSON Start");
         if (debug) log("=========================================================");
       
         var anyLueften          = false;
         var countLueften        = 0;
         var raeumeLueftenListe  = [];
         
         var temppfad = "";
         var tempraum = "";
         var tempVal = "";
         var strJSONfinal = "[";
         var strJSONtemp = "";
       
         for (var raum in raeume) {
             strJSONtemp = strJSONtemp + "{";
             strJSONtemp = strJSONtemp + "\"Raum\":\"" + raum + "\",";
       
             for (var datenpunktID in raumDatenpunkte) {
                 
                 // Aussensensor ja oder nein 
                 var aussensensor = false;
                 if (lueftenDp(datenpunktID)) {
                     if (!raeume[raum].Aussensensor) {
                         aussensensor = true;
                     }
                 }
                 
                 temppfad = pfad + raumPfad + raum + "." + raumDatenpunkte[datenpunktID].DpName;
                 tempraum = pfad + raumPfad + raum;
       
                 tempVal = (!aussensensor ? getState(temppfad).val : "");            // kein Aussensenosr: Lüftungsempfehlung auslesen, Aussensensor: Lüftungsempfehlung freilassen
                 if (tempVal === null) tempVal = "";
                 if(raumDatenpunkte[datenpunktID].DpName != "Lüftungsempfehlung") {
                     tempVal = parseFloat(tempVal);
                     tempVal = tempVal.toFixed(2);
                 } else {
                     if (tempVal === true) {
                         anyLueften = true;
                         countLueften = countLueften + 1;
                         raeumeLueftenListe.push(raum);
                     }
                 }
                 strJSONtemp = strJSONtemp + "\"" + raumDatenpunkte[datenpunktID].DpName + "\":\"" + tempVal + "\",";
                 
             }
             strJSONtemp = strJSONtemp.substr(0, strJSONtemp.length - 1);
             strJSONtemp = strJSONtemp + "},";
       
         }
       
         strJSONtemp = strJSONtemp.substr(0, strJSONtemp.length - 1);
         strJSONfinal = strJSONfinal + strJSONtemp + "]";
         if (debug) log("strJSONfinal = " + strJSONfinal);
         if (debug) log("anyLueften = " + anyLueften + ", Anzahl Lüftungsempfehlungen: " + countLueften);
         
         
         setState(pfad + 'Lüften'                    , anyLueften);
         setState(pfad + 'Lüften_Liste'              , writeJson(raeumeLueftenListe));
         setState(pfad + 'Lüften_Anzahl'             , countLueften);
         setState(pfad + 'JSON'                      , strJSONfinal);
         setState(pfad + 'Aktualsierung'             , formatDate(new Date(), strDatum));
         
         if (debug) log("=========================================================");
         if (debug) log("Erzeugung JSON Ende");
         if (debug) log("=========================================================");
      }
      // eric2905 Ende ---------------------------------------------------------------
       
       
       
       
      function calcDelayed(raum, delay) {
         setTimeout(function () {
             calc(raum);
         }, delay || 0);
      }
       
      function creatJSONDelayed() {
         setTimeout(function () {
             createJSON();
         }, 4000); 
      }
       
      // Klimadaten in allen Räumen berechnen 
      function calcAll() {
         for (var raum in raeume) {
             calcDelayed(raum,delayRooms);       // Räume verzögerd nacheinander abarbeiten
         }
      }
       
       
      // finde anhand der Sensor ID einen zugeordneten Raum
      function findRoom(sensor) {
         for (var raum in raeume) {
             if (raeume[raum].Sensor_TEMP == sensor) return raum;
             if (raeume[raum].Sensor_HUM == sensor) return raum;
         }
         return null;
      }
       
      // Änderung eines Sensors (Temperatur oder Luftfeuchtigkeit)
      function valChange(obj) {
         var raumname = findRoom(obj.id);
         if (raumname) {
             if (debug) log('<span style="color:black;"><b>Änderung:' + raumname + ": " + obj.id + ": " + obj.state.val + '</b></span>');
             calcDelayed(raumname,delayRooms);
         }
         // eric2905 Aufruf eingebaut zum JSON erzeugen und Datenpunkt befüllen
         // -----------------------------------------------------------------------------
         creatJSONDelayed();
         // eric2905 Ende ---------------------------------------------------------------
      }
       
       
      // Datenpunkte für alle Räume anlegen
      function createOn() {
         var dpId    = "";
       
         // TODO: Im Modus CONTROL über Objekte: Bei Änderung der OFFSETS, Temperatur_Minimum werden die Änderung erst nach Aktualisierung der Messwerte oder nach Zeit erneuert (auf on() reagieren) 
         var i =0;
       
         for (var raum in raeume) {
       
             if (raeume[raum].Sensor_TEMP) {
                 dpId = raeume[raum].Sensor_TEMP;
                 i++;
                 on({id: dpId ,change:'ne'}, function (obj) {
                     valChange(obj);
                 });
                 if (debug) log("on: " + dpId + " angelegt.");
             }
       
             if (raeume[raum].Sensor_HUM) {
                 dpId = raeume[raum].Sensor_HUM;
                 i++;
                 on({id: dpId ,change:'ne'}, function (obj) {
                     valChange(obj)
                 });
                 if (debug) log("on: " + dpId + " angelegt.");
             }
         }
         log("Subscriptions angelegt: " + i);
      }
       
       
       
      // Schedule
      // =============================================================================
       
      // Nach Zeit alle Räume abfragen
      schedule(cronStr, function () {
         calcAll();
         // eric2905 Aufruf eingebaut zum JSON erzeugen und Datenpunkt befüllen
         creatJSONDelayed();
         // eric2905 Ende ---------------------------------------------------------------
      });
       
       
      // main()
      // =============================================================================
       
      function main() {
         calcAll();
         setTimeout(calcAll,2000);
         // eric2905 Aufruf eingebaut zum JSON erzeugen und Datenpunkt befüllen
         creatJSONDelayed();
         // eric2905 Ende ---------------------------------------------------------------
      }
       
       
      // Skriptstart
      // =============================================================================
       
      createDp();                 // Datenpunkte anlegen
      setTimeout(createOn,2000);  // Subscriptions anlegen
      setTimeout(main,    4000);  // Zum Skriptstart ausführen
      

      Das war Dank @OliverIO kein großes Problem.

      posted in JavaScript
      BananaJoe
      BananaJoe
    • RE: Starter Set open ePaper

      @david-g sagte in Starter Set open ePaper:

      Kommunikation läuft vermutlich über Bluetooth zu den Displays?
      Also nicht ein AP fürs ganze Haus?

      Im Prinzip sind es die WLAN und ZigBee Frequenzen (also eine Überschneidung damit), aber wohl eigenes Protokoll.
      Man kann problemlos mehrere APs einsetzen, so etwas wie Repeater gibt es nicht. Die APs finden sich untereinander so das man über einen auch alle Displays (aka Tags) steuern kann. Die Tags können Roaming und suchen sich den stärksten AP

      Siehe auch hier im Forum: https://forum.iobroker.net/topic/66380/e-ink-display-openepaperlink-displayanzeige-mit-batterie
      Oder auf der Projekt-Webseite: https://openepaperlink.de/

      Ich habe Tags (E-Paper-Tags = Die Displays) für verschiedene Aufgaben, ein 4,7" hängt neben den Eingang und zeigt offene Fenster und Türen an, ein 2,4" zeigt an ob etwas im Briefkasten liegt, ein anderes die Temperaturen im Kühlschrank.
      Der kleinste Intervall sind 3 Minuten. Laufzeit der Batterien hängt stark davon ab wie oft die Information sich ändert, die APs übertragen - im Normalfall - nur wenn sich etwas geändert hat. Man kann also 20x die gleiche Info senden, erst wenn sich etwas geändert hat, senden die APs auch.
      So 1 bis 2 mal im Jahr brauchen die stark beanspruchten Tags schon neue Batterien. Bei meinen Kühlschrankdisplay wird wirklich alle 3 Minuten neu gesendet und da sind es - ganz genau weiß ich es nicht - 4 bis 6 Monate

      Edit: Typos

      posted in Marktplatz
      BananaJoe
      BananaJoe
    • RE: Balkonkraftwerk mit FritzDect-Verständnisproblem

      @rosi8818

      wie @paul53 geschrieben hat: Wenn du z.B. auf L1 einspeist wird die erzeugte Energie auch direkt von allen Verbrauchern die ebenfalls an L1 hängen verbraucht.

      Hast du dann auf L1 einen Überschuss, die Anlage produziert z.B. 500 Watt, du verbrauchst auf L1 aber nur 200 Watt, dann werden 300W in das öffentliche Netz eingespeist.

      Aber - auch wenn dein Stromzähler nicht rückwärts läuft, so kumuliert er aber:

      L1 - du speist 300W ein
      L2 - bezieht gerade 100W aus dem Netz
      L3 - bezieht gerade 200W aus dem Netz

      Dann bleibt der Zähler stehen - er verrechnet plus und minus in Summe.

      L1 - du speist 300W ein
      L2 - du beziehst 500W
      L3 - du beziehst 100W

      Dann würde der Zähler nur 300W zählen.

      Du sparst also egal auf welcher Phase du einspeist. Der innere Monk möchte eventuell die Phase nehmen auf der auch der meiste Verbrauch ist.

      posted in Off Topic
      BananaJoe
      BananaJoe

    Latest posts made by BananaJoe

    • RE: Kaffeevollautomat - was bedeuten die Rezepte

      @martinp Wir eigentlich auch, meine Frau schwört auf Filterkaffee.
      Aber den Vollautomat gab es zwar nicht umsonst, aber kostenlos. Und so uncool ist der gar nicht.

      posted in Off Topic
      BananaJoe
      BananaJoe
    • RE: Kaffeevollautomat - was bedeuten die Rezepte

      @crunchip sagte in Kaffeevollautomat - was bedeuten die Rezepte:

      @bananajoe sagte in Kaffeevollautomat - was bedeuten die Rezepte:

      Unterschied zwischen Filterkaffe und Filterkaffee to go

      ist glaub ich die Zubereitungszeit......to go....wenns schnell gehn muss

      Die Menge ist höher, er nimmt etwas mehr Wasser und macht das ganze 2x (habe ich durch ausprobieren heraus bekommen).

      Mal sehen ob etwas von deren Kundensupport kommt.

      schau dir mal das video an
      https://www.youtube.com/watch?v=hkw7vZa5h14

      sieht verdächtig ähnlich aus wie mein frisch und gerade erst 2025 auf den Markt gekommenes Gerät ... meine Tasten sind bunter, die Anbauteile, Wassertank und Satzbehälter, da würden ich wetten das es die gleichen sind. Selbst das Display sieht 1:1 genauso aus.

      posted in Off Topic
      BananaJoe
      BananaJoe
    • RE: [ERLEDIGT] Fragen zu Eltako Hutschienenaktor

      @homoran wie wäre denn so etwas: https://www.amazon.de/dp/B0DMWSVM86
      2a394f40-ee5e-46ea-9e3e-d08875e1b41b-image.png

      Gibt es bis 25A, setzte ich bei mir mehrfach zum Stromessen ein (hinter der Sicherung und vor den Shelly 1 / Shelly Pro 3 / Stromstoßschalterersatz).
      Wird im Gegensatz zu den Shelly 1PM kaum warm.
      Braucht WLAN und hat keinen Schalteingang, kann also nur über Software geschaltet werden (oder dem Knopf vorne).

      Aber nur 1TE!

      Danach käme ein Shelly Pro 1PM, der hätte noch extra LAN und einen Schalteingang und wäre bis 16A,
      der Shelly Pro 2PM hätte 2 Schaltkreise bei gleicher Größe, beide auch mit 16A.
      Die wären dann auch noch jeweils 1TE

      posted in Off Topic
      BananaJoe
      BananaJoe
    • Kaffeevollautomat - was bedeuten die Rezepte

      Ja, schon sehr Offtopic, aber ich finde dazu einfach nichts:

      Wir haben seit kurzen einen Kaffeevollautomaten von Krups: https://www.krups.de/p/evidence-hot-cold-kaffeevollautomat-ea898gf/8010001375
      Funktioniert toll, die Anleitung besteht quasi nur aus Bildern, es gab ein paar Videos - ok, wir kommen zurecht.

      Was mir aber ein Rätsel sind, sind die eingebauten Rezepte.
      Klar, einen Cafe Creme oder ein Espresso, da weis ich was das ist.
      Aber das Ding hat in Wirklichkeit mehr als die 18 Rezepte.
      Es gibt einen Filterkaffee - dann pumpt er das Wasser stoßweise. Aber was ist der Unterschied zwischen Filterkaffe und Filterkaffee to go, was macht er genau bei den 3 verschiedenen Teeprogrammen und so weiter.
      Und das Gerät wird mit Erleben Sie den vollen Geschmack Ihres Kaffees mit perfekt abgestimmter Kalt-Extraktion beworben - ich habe da noch kein Programm gefunden wo er nicht heißes Wasser verwendet.

      Sprich, ich hätte gerne irgendeine Übersicht was welches Programm, welcher Zusatz bedeutet. Vorher, und nicht durch ausprobieren.
      Ich habe zwar den Kundendienst gerade angeschrieben ( https://www.krups.de/contact )
      aber vielleicht gibt es so etwas ja schon irgendwo und ich war nur nicht in der Lage das zu finden.

      Ich würde mir gerne eine View dazu bauen, ein Tablet hängt gleichen neben dem Kaffeevollautomat.

      Gruß,
      BananaJoe

      posted in Off Topic
      BananaJoe
      BananaJoe
    • RE: Test Adapter Midea Dimstal Klimaanlagen v0.0.x

      @hantschel sagte in Test Adapter Midea Dimstal Klimaanlagen v0.0.x:

      Kann mir da jemand helfen?

      Wie weit bist du denn? Weiter oben werden ja verschiedene Methoden beschrieben,
      das aktuellste per Skript ab hier https://forum.iobroker.net/post/1277642

      Auf https://pypi.org/project/msmart-ng/ weiter unter bei Usage werden die CLI-Befehle beschrieben,
      mit

      msmart-ng discover
      

      sollte er alle 3 Geräte finden mit den notwendigen Daten mit denen du dann das Gerät schalten kannst.
      Du könntest https://forum.iobroker.net/post/1281163 das Skript übernehmen (dann 3 mal für jede Anlage separat).

      Alternativ: Falls du schon Alexa im Einsatz hast, den Skill installieren (Midea?), dann kannst du die Anlagen per Sprachbefehl und Textbefehl über den Adapter steuern (über den Command-Datenpunkt eines Echos),
      Die Daten selbst bekommst du ja über den Midea Adapter

      posted in Tester
      BananaJoe
      BananaJoe
    • RE: Anzeige ob Strom auf Leitung

      @martinp sagte in Anzeige ob Strom auf Leitung:

      @homoran okay, ich habe nicht an die Router Funktionalität gedacht, die Netzbetriebene Geräte in einem Zigbee Netz ausfüllen. Der Ausfall eines Routers kann ein Netz schon durcheinanderbringen.

      Ich nutze zu Hause die Heimann ZigBee Sirenen: https://de.aliexpress.com/item/1005007332696400.html
      Sind Repeater, haben aber auch einen internen Akku, funktionieren also bei einem - nicht zu langen Stromausfall - einfach weiter. Und können nebenbei Alarm schlagen, gesteuert aus ioBroker

      posted in Hardware
      BananaJoe
      BananaJoe
    • RE: Anzeige ob Strom auf Leitung

      @negalein Ich bin ja schon etwas älter und kenne noch so etwas:

      https://www.amazon.de/dp/B0CZQTRD6R oder https://www.amazon.de/dp/B00Y3PFAU8
      oder
      https://www.amazon.de/dp/B07ZFWSCXR

      Machen Lärm oder senden sogar Nachrichten, da gibt es bestimmt noch mehr.

      posted in Hardware
      BananaJoe
      BananaJoe
    • RE: Adapter Worx Landroid v3.x.x

      Ich habe meinen Landroid erst seit kurzen, auch gekauft wegen der Anbindung an ioBroker.
      Als hier die Probleme auftauchten, hatte ich auch Probleme in der App mit den Zeitplänen, die hat er immer gleich wieder vergessen, den Adapter hatte ich da gar nicht erst aktiviert.

      Seit dem der Korken scheinbar raus ist, klappt es auch mit der App wieder. Und den Adapterzugriff eingerichtet, sieht unauffällig aus, keine Probleme beim Zugriff, mehr als starten und wieder nach Hause schicken habe ich per Adapter noch nicht getestet, klappt aber ohne Probleme.

      posted in Entwicklung
      BananaJoe
      BananaJoe
    • RE: Test Adapter VW Connect für VW, ID, Audi, Seat, Skoda

      @sabinet also bei meinem Tiguan gibt es kein

      vw-connect.0.FIN.status.vehicle-status.driving-range.carType
      

      aber

      vw-connect.0.FIN.status.fuelLevelStatus.carType
      vw-connect.0.FIN.status.rangeStatus.carType
      

      und in beiden steht als Wert hybrid
      Im Adapter:
      691a7d8c-34b9-4ba7-9cdd-b950335ac0e5-image.png

      posted in Tester
      BananaJoe
      BananaJoe
    • RE: Welche Container habt ihr so im Einsatz?

      @david-g und bei @Meister-Mopper , hab ich beim ersten mal überlesen 😞
      Dafür besser vorgestellt 🙂

      posted in Docker
      BananaJoe
      BananaJoe
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo