Navigation

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

    NEWS

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    • Profile
    • Following 25
    • Followers 11
    • Topics 62
    • Posts 5193
    • Best 869
    • Groups 3

    BananaJoe

    @BananaJoe

    Most Active

    1057
    Reputation
    366
    Profile views
    5193
    Posts
    11
    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

    • [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: 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
    • 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: [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: 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: Suche Zigbee Luftentfeuchter

      Ich nutze einen Klarstein DryFy in der 30L Version, der hatte auf Amazon 160 Euro gekostet - ist im Moment ausverkauft weil wohl gerade alle auf die Idee kommen.

      Lässt sich per Tuya App einbinden und dann auch per Tuya-Adapter super steuern (Also per WLAN).
      Erfahrungswerte:

      • Erst einmal ist das total klasse und ich hätte das schon viel eher machen sollen. Wir hatten im Oktober das wieder mal das Problem das bei 4 Leuten die 5 Duschvorgänge am Tag produzieren und Regenwetter das Bad gar nicht mehr richtig trocken wurde und an der Decke die ersten Schimmelflecken kamen. Die Decke besteht zum Glück aus Kunststoffpanelen und lies sich leicht reinigen, seitdem der Luftentfeuchter da ist, ist das Problem weg und die Handtücher immer trocken
      • Blöd nur das das Ding auch ordentlich Strom verbraucht wenn es quasi nur im Überwachungsmodus läuft (300W)
      • Ich habe ebenfalls einen ZigBee Sensor im Bad für Temperatur und Luftfeuchte. Wenn der Luftentfeuchter und der ZigBee-Sensor beide eine Überschreitung des Grenzwertes (bei mir meist 60%, Grenzwert + 10%) melden geht das Ding an.
      • Wenn beide den Zielwert unterschritten haben geht das Ding aus
      • Morgens geht es Zeitgesteuert um 05:30 an und läuft bis 7:00 durch => Bad ist trocken, den morgentlichen Ansturm gewachsen und auch noch angenehm warm
      • Wenn das Fenster geöffnet wird, wird abgeschaltet.

      3df05454-7f50-494e-8b73-285df829317d-image.png

      posted in Hardware
      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: 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: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      @haselchen wie @Revobobo schreibt: Ich füttere meine ePaper Tags einfach mit einem eigenen VIS-Projekt. Jedes Tag hat seine eigene Seite, bei Änderungen lasse ich per Script/Blockly einen neuen Screenshot erzeugen. Den pushe ich wahlweise an das Tag oder lasse es sich per URL abholen:
      2024-01-16 23_01_45-Edit vis.png
      2024-01-16 23_05_43-vis.png
      Das Tag hängt über dem Briefkastenschlüssel. Und zeigt an ob Briefe oder Pakete oder beides in der Box liegen.
      Ist diese leer wird der Akkustand des Shelly-Buttons am Briefkastenschlüssel angezeigt mit dem ich die Meldung zurück setze.

      2024-01-16 23_06_45-Edit vis.png
      Die Anzeige die neben der Haustür hängt. So kann man bei Verlassen des Hauses sehen ob noch ein wichtiges Fenster offen ist:
      2024-01-16 23_09_12-vis.png

      Und eine Akku Anzeige für meine Solarbatterie:
      2024-01-16 23_10_19-vis.png

      Und ich hab noch ein Dutzend oder mehr hier liegen die noch auf Verteilung/Einsatz warten. Für die 1,54 Zoll habe ich noch keinen Einsatzzweck.
      Ich hatte recht schnell Verbindungsprobleme und mir erst einmal einen 2. AP besorgt. Jetzt ist das Haus gut abdeckt und ich könnte weiter machen (So viele Projekte, so wenig Zeit)

      posted in Praktische Anwendungen (Showcase)
      BananaJoe
      BananaJoe

    Latest posts made by BananaJoe

    • RE: sento to photo

      @kellerkind-86 du baust dir den Dateinamen auf Basis der Uhrzeit (-2 Sekunden) zusammen. Wie weist du denn das es diesen speziellen Namen wirklich gibt?
      Du solltest eher die neueste Datei oder so etwas nehmen.

      posted in JavaScript
      BananaJoe
      BananaJoe
    • RE: Festplattenbedarf iobroker 14GB ? Normal oder ... ?

      @oliverio sagte in Festplattenbedarf iobroker 14GB ? Normal oder ... ?:

      Das auftrennen macht aber auch bei kleinen Installationen Sinn, da dann die Abhängigkeiten so gering wie möglich gehalten werden.

      Und aus meiner Sicht ist das ein Widerspruch, die Abhängigkeiten sind nicht kleiner sondern nur Container-übergreifend.
      Ich nutze durchaus auch Docker-Container (ja das sind keine LXC-Container), vieles wie z.B. Vaultwarden gibt es ja quasi gar nicht anders. Oder z.B. ZigBee2MQTT.
      Trotzdem ist das bei einem Upgrade von ZigBee2MQTT mist wenn ich dem ioBroker-Adapter (und dem Home Assistant) im laufenden Betrieb die Verbindung weghaue. Ok, das ist ein Beispiel wo - vermutlich - nichts schlimmes passiert.

      Native LXC-Container finde ich zum Beispiel für mich in dem Sinne doof, als das ich diese nicht im laufenden Betrieb verschieben/migrieren kann. Aber auch Docker-Container laufen bei mir deshalb z.B. in einer VM damit die Live-Migration möglich ist.

      Wobei ich schweife ab: Es bleibt dabei das 14G Festplattenplatz "normal" sind und man wegen 2 bis 3G keinen Aufriss machen sollte. Der belegte Speicherplatz kostet nur Platz, aber keine Perfomance

      posted in Einsteigerfragen
      BananaJoe
      BananaJoe
    • RE: SmartTV einschalten

      @stefanw ja, da ist der Eingebaut. Der Fernseher (mein Sohn hat einen mit Amazon gelabelten) kann etwas mehr als nur der FireTV Stick, z.B. kann der direkt Kabelfernsehen oder Satellit. Gibt also ggf. ein paar Menüpunkte mehr.

      Das hier ging vor ca. 2 Jahren: https://forum.iobroker.net/topic/68901/fire-tv-fernseher-erfahrungen/14?_=1747989800192
      Eventuell geht da inzwischen mehr

      Irgendwo hier im Forum gab es auch noch ein "Popup" Projekt mit dem man Meldungen einblenden könnte (für FireTV).

      posted in Hardware
      BananaJoe
      BananaJoe
    • RE: Festplattenbedarf iobroker 14GB ? Normal oder ... ?

      @dr-bakterius sagte in Festplattenbedarf iobroker 14GB ? Normal oder ... ?:

      Da gab es bei mir noch nie Probleme - ioBroker läuft einfach weiter.

      Wenn du die denen die Datenbank mitten im Betrieb wegnimmst (oder was anderes), ist das Glücksache was passiert. Der SQL-Adapter wirft vielleicht nur ein paar Fehlermeldungen, der Nextcloud schafft es ggf. nicht einen Dateieintrag zu schreiben, dem Seafile fehlen ggf. Dateiblöcke, meinen Zabbix fehlen ein paar Messdaten. Bei allen gibt es Massenhaft Logeinträge.

      Das macht man einfach nicht, auch wenn "es bei mir noch nie Probleme" gab, das sollte ich mich mal bei einem Kunden trauen. Nein, das geht gar nicht, da blutet mein Herz. Das ist aus meiner Sicht reine Glückssache, das geht 1.000 mal gut und einmal schief.

      Firmen haben da ein Change-Management, da wird auch das Einspielen von Updates als Change behandelt. Dazu gehören dann auch Abhängigkeiten, sprich wenn ich Komponente A anfasse wird beachtet was davon abhängt. Und die Kette kann sehr lang werden wenn man sich das ungünstig baut.
      Fazit bei so etwas in Firmen ist z.B. das der zentrale Datenbankserver nie gepatched wird wenn da statt nur einem Dienst dann 20 dranhängen und man das dann eigentlich nur einmal im Jahr machen könnte wenn die Produktion mal steht (Klar, andere Möglichkeiten wie z.B. Cluster einsetzen)

      posted in Einsteigerfragen
      BananaJoe
      BananaJoe
    • RE: SmartTV einschalten

      @stefanw öhm genau, was konnten eigentlich die FireTV-Fernseher von Amazon in der Hinsicht ...
      Die kann man auf jeden Fall ja per Sprache steuern, sprich was per "Sprache" geht würde auch über den Alexa2 Adapter gehen

      Edit: ok, die scheint es zur Zeit nicht mehr zu geben ...

      Heißen nur anders: https://www.amazon.de/dp/B0CF5ZQH7Y 150 Euro für 32 Zoll,

      posted in Hardware
      BananaJoe
      BananaJoe
    • RE: SmartTV einschalten

      @stefanw Notfalls per Umweg. Ein IR-Sender kann z.B. auch einen Fernseher einschalten und einen Kanal wählen.
      Wenn der Fernseher schon eine Bluetooth-Fernbedienung hat ist natürtlich schlechter, außer man kauft einfach eine 2. und steuert die dann z.B. elektronisch/per Relais an.

      Da ist aber immer auch die Frage wie schnell das geht.

      Tablet z.B. mit WaipuTV (oder anderer App für Fernsehen) könnte auch gehen, der Fully Kiosk kann ja z.B. aus der Ferne/per Adapter gesteuert werden und auch andere Apps starten.
      Oder Monitor/Touch Monitor + Raspi und z.B. Kodi, das kann man auch Fernsteuern und es gibt auch dafür Plugins zum Fernsehen.
      Wenn du Kabelfernsehen hast und auf der FRITZ!Box das lokale Streamen einschaltet hast, könnte eine URL reichen (Habe ich aber nie gestetet).

      Wenn es ein öffentlich-rechtlicher Sender ist, könnte Tablet + Fully Kiosk + URL für den Livestream reichen.
      Oder Raspi, Monitor und Kodi

      posted in Hardware
      BananaJoe
      BananaJoe
    • RE: [verschoben -> github] Emporia Adapter: Logging ausschalten

      @fuzzy1955 sagte in Emporia Energy Adapter: Logging kann man nicht ausschalten:

      Übersehe ich da etwas oder kann man das tatsächlich nur durch die Protokollstufe "warn" ausblenden?

      Nö, kann schon angehen. Was bei Info rausgehauen wird, liegt im Ermessen des Entwicklers des Adapters

      posted in ioBroker Allgemein
      BananaJoe
      BananaJoe
    • RE: Festplattenbedarf iobroker 14GB ? Normal oder ... ?

      @topsurfer also, es ist doch nur Speicherplatz. Und nicht viel bei dir.

      Ja, snap belegt bei mir auch 2,7GB (obwohl ich da nichts bewusst benutze) und du lässt da bitte den Finger von weil Ubuntu das auch ggf. für den Kernel und Updates verwendet.

      Mein iobroker hat eine 64GB Festplatte und davon sind im Moment 36GB belegt, z.B.
      2,7GB Snap,
      7,2GB von npm, 3,6GB Cache
      2GB das Swapfile
      5GB meine MySQL Datenbank mit den historischen Daten

      Hast du schon Platznot auf deinem Proxmox Host?

      Viel wichtiger wäre mir das man die Festplatte meiner ioBroker VM leicht vergrößern kann.
      Da musste ich neulich entdecken das auch ein Debian 12 immer noch eine extra Partition für Swap anlegt (Installation ohne LVM) die natürlich störend am Ende der Festplatte liegt.

      Ob du nun die Daten für DB in eine extra VM legst, ist eine Glaubensfrage.
      Denn du schaffst die mehr Abhängigkeiten.
      Du hast VM A mit iobroker und VM B mit deiner Datenbank?
      Du spielst Updates auf VM B ein? Da musst du dann eigentlich VM A vorher stoppen (oder zumindest die Dienste welche VM B brauchen).
      Und wenn du das dann noch weiter auseinander ziehst, zum Beispiel Redis ein extra Server, dann hats du immer mehr was du beachten musst.

      Ich bin deshalb ein Freund davon, Dinge die zusammengehören bzw. von einander abhängig sind auf eine VM zu packen. Muss ich ja eh zusammen betrachten und neu starten.

      Und dann hat halt jede Linux VM bei mir ihren eigenen MySQL / MariaDB Server mit jeweils seiner eigenen Datenbank - ioBroker, Webserver 1 und 2, Zabbix Server, Netxcloud, Seafile
      Und Ihre eigene Redis Installation - iobroker und Nextcloud.

      Muss aber auch auf nichts anderes achten und ich kann so durchpatchen. Oder so einen Snapshot machen vor Updates/Upgrades , die passende Datenbank wird dann ja mit gesnapshotet, sonst müsste ich den ja auf 2 System gleichzeitig machen und beim Wiederherstellen würde ich ja Datenbanken von anderen Systemen mit wiedergestellt.

      VMs /Container sind durchaus dafür gedacht, alle Dienste in jeweils ein extra System zu installieren.
      Damit sind aber nicht(!) unbedingt Webserver, Datenbank, ioBroker, Redis usw. gedacht.
      Sondern ioBroker ist ein Dienst. Wenn der eine Datenbank braucht, gehört die mit zum Dienst ioBroker

      Das auftrennen machst du bei großen Installationen wenn es um Performance geht.
      Bei mir zu Hause läuft Nextcloud in einer VM, da nutzen es aber auch nur 8 Personen.

      Bei einem meiner Kunden läuft Nextcloud auf 15 VMs, 6 Frontend Webserver, 3 Server MariaDB Cluster, 3 Server Redis Cluster und 3 Server Gluster Fileserver. Da arbeiten aber auch um die 6.000 Leute drauf.

      posted in Einsteigerfragen
      BananaJoe
      BananaJoe
    • RE: Einstieg in Smarthome —> Rollladen

      @wendy2702 ich habe bei mir trotzdem einen Endschalter eingebaut (der genau das gleiche macht, den Motor vom Strom trennen).
      Grund ist das bei meiner Jalousie extrem wenig Spielraum in der oberen Position ist. Zu hoch und die Jalousie wird so eingezogen das der Deckel verzieht, zu niedrig und die Fliegengittertür vor der Terrassentür lässt sich nicht öffnen.
      Und das in einem Bereich von unter 1cm

      posted in Off Topic
      BananaJoe
      BananaJoe
    • RE: Einstieg in Smarthome —> Rollladen

      @wendy2702 Im Notfall beim Kalibrieren den Strom trennen (also zum Motor), das nimmt er dann auch als "Ende".

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