Skip to content

Skripten / Logik

Hilfe zu JavaScript, Blockly, TypeScript, Node-RED, Scenes und text2command

16.4k Themen 211.8k Beiträge

NEWS

Unterkategorien


  • Hilfe für Skripterstellung mit JavaScript

    2k 48k
    2k Themen
    48k Beiträge
    D
    @maxclaudi Vielen Dank für das ausführliche oben beschriebene Verhalten von smartMode. Es gibt wirklich keine konstante wann er umschaltet. Hatte erst mal.4 Tage ohne umschalten und dann kann sein das er 3 mal am tag umschaltet
  • Hilfe für Skripterstellung mit Blockly

    6k 78k
    6k Themen
    78k Beiträge
    Dr. BakteriusD
    Hallo! Ich habe mir eine Aquariumbeleuchtung mit RGBCCT-LED-Streifen gebaut. Zu unterschiedlichen Tageszeiten sollen bestimmte RGB Farben und Warm- bzw. Kaltweiß dargestellt werden. Dazu habe ich mir mit Zigbee2MQTT die Farben und Helligkeiten so eingestellt wie ich sie haben möchte und die Werte in mein Skript übernommen. So kann man praktisch die Farbmischung in RGB einstellen. Um die Farbe an dem Controller zu ändern, benötige ich aber den Hex-Wert. Dafür gibt es doch in Blockly den Baustein 'Farbe aus...". Man übergibt die RGB-Werte in Dezimal und erhält als Ergebnis den Hex-Wert. Sollte man denken! Die Farben die mein Skript produzierte unterschieden sich teil enorm von der manuell eingestellten Farbe. Also habe ich mir mal die Ergebnisse angesehen und mit den errechneten Hex-Werten verglichen und habe festgestellt, dass der Block falsch umrechnet. Ich habe mir also selbst eine kleine Javascript-Funktion geschrieben und die Ausgabe verglichen: function prependZeroIfSingleChar(text) { return text.length === 1 ? "0" + text : text; } RED = prependZeroIfSingleChar(R.toString(16)); GREEN = prependZeroIfSingleChar(G.toString(16)); BLUE = prependZeroIfSingleChar(B.toString(16)); return "#"+RED+GREEN+BLUE;return 0; [image: 1764062753624-screenshot-2025-11-25-102502.png] Das Ergebnis sieht dann so aus: [image: 1764062778666-screenshot-2025-11-25-101249.png] Hat das schon jemand beobachtet oder kann es nachvollziehen? Was läuft da falsch?
  • Hilfe für Skripterstellung mit Node-RED

    952 13k
    952 Themen
    13k Beiträge
    HomoranH
    @fiddle sagte in [Gelöst]: Adapter per {Node Red | JS} (de)aktivieren: Ok, nicht als "Wert" schreiben, sondern als "Befehl". Dann scheint ihn das zu beeindrucken. du zeigst ja nichts, aber es geht mit true/false [image: 1763416200051-screenshot_20251117-224854_firefox.jpg] gesteuert über eigenen DP vom typ Bool
  • Remote Uptime von Debian auslösen

    Verschoben
    7
    0 Stimmen
    7 Beiträge
    425 Aufrufe
    K
    Hab jetzt auf dem ioBroker ein Shell Skript geschrieben uptime=$(ssh root@192.168.4.32 uptime | awk -F'( |,|:)+' '{print $6,"Tage,",$8,"Stunden,",$9,"Minuten"}') iobroker state set javascript.0.zeiten.uptime_unifi_controller $uptime Leider wird immer nur das erste Zeichen in das Objekt geschrieben
  • Fehlerhafte Darstellung beim Script Editor

    Verschoben
    5
    0 Stimmen
    5 Beiträge
    767 Aufrufe
    R
    Hallo, Hat funktioniert….Danke schön.
  • Mit RFXcom verschiedene sensoren auslesen

    Verschoben
    2
    1
    0 Stimmen
    2 Beiträge
    943 Aufrufe
    R
    Hallo tomwein, Eine Frage von einem Anfänger. Wie hast du es geschafft Daten über den RFXcom und den Sensoren zu in den IOBroker zu bekommen. Habe den RFXcom Adapter versucht, bekomme aber keine Daten meines Sensors. Danke und Gruß Rico
  • [gelöst] Datenpunkt in Script neu einlesen

    Verschoben
    6
    0 Stimmen
    6 Beiträge
    605 Aufrufe
    PeoplesP
    Genau das habe ich gesucht Tausend Dank! Zwei kurze Fragen noch, den Datenpunkt via setState auf false und true setzen oder besser setStateDelayed? Und umsetzen muss ich das ganze wahrscheinlich in einem seperaten Script da das laufenden ja gestoppt wird oder?
  • Steckdose Schalten nach Wetterdaten

    Verschoben
    2
    0 Stimmen
    2 Beiträge
    453 Aufrufe
    Jey CeeJ
    Wenn du hier mehr Informationen Preis gibst bekommst du bestimmt auch hilfreiche Antworten. Das es machbar ist steht absolut außer Frage. Deine Anfrage ist etwas Unspezifisch. Keine Informationen zur verwendeten Hardware, keine Angabe darüber welche Programmiersprache (Kenntnisse) vorhanden sind und wie der Zeitplan aussehen soll oder in welcher Form er vorliegt.
  • [gelöst]Blockly Ansage Vorraumlicht

    Verschoben
    9
    1
    0 Stimmen
    9 Beiträge
    647 Aufrufe
    sigi234S
    DANKE!!! Es funktioniert jetzt. Ausschlaggebend ist anscheinend wurde geändert und falls Objekt: hm-rpc.1….......................
  • Broadlink - Szenen - Node-Red - Alexa - PROBLEM

    Verschoben
    16
    2
    0 Stimmen
    16 Beiträge
    2k Aufrufe
    M
    Habe ich. Jetzt kommt die Meldung: 13.6.2018, 15:10:55node: caf87856.10a578 msg : error "TypeError: node.findAlexaHomeController is not a function"
  • [Vorlage] WLANthermo Script

    Verschoben
    17
    0 Stimmen
    17 Beiträge
    3k Aufrufe
    M
    Habe bei mir keinen MQTT Adapter laufen, meine NodeMCUs sprechen REST und beschicken Selbstbaukrams. Bin gerade unterwegs, kann nicht nachsehen. Aber suche mal in der Adapterliste. Da gibts nen Client und einen Server, soweit ich mich erinnere. Den Server wirst Du brauchen. Ich gehe davon aus aus, dass Du noch keinen anderen hast.
  • Script oder Blocky für Objektabfragung gesucht

    Verschoben
    7
    0 Stimmen
    7 Beiträge
    555 Aufrufe
    A
    schaut interessant aus. muss ich dann mal testen. versteh ich richtig? er Fragt damit alle Datenpunkte ab, die das Wort "schalter" beinhalten!? d.h. ich muss nix erweitern und es läuft immer so weiter, ich muss nur wenn ich welche hinzufüge diese auch mit Schalter benennen. bei Blocky könnte man es vergessen den neuen Daenpunkt hinzuzufügen…. genail . danke
  • Seit dem Javascript Adapter Update –-Fehlermeldung

    Verschoben
    7
    0 Stimmen
    7 Beiträge
    2k Aufrufe
    M
    Hi…mein Problem das ich noch nicht genau weiß wie die Fehlermeldung und Script lesen soll ! Gibt es dazu eine Anleitung. Ständig Fragen nervt. :roll: Wie es ja auch lernen.... Hier mein Script dazu: ! // AlexaControl ! // ! // Version: v0.1.6 ! // Author: Hauke ! // Dank an ruhr70 dessen Skript als Vorlage diente ! // http://forum.iobroker.net/viewtopic.php?f=37&t=6035 ! // und Stefan.Franke, dessen Skript den Login per Cookie ermöglicht ! // http://forum.iobroker.net/viewtopic.php … gOn#p98493 ! // Changelog: ! // v.0.1.6 Fehler behoben: Cannot use 'in' operator to search for 'provider' in undefined ! // v.0.1.5 Dummy-Objekte, falls Alexa {"message":null} antwortet, weil das Device derzeit nicht aktiv ist ! // v.0.1.4 Spielzeit und Titellänge werden nun im 2-Sekunden-Takt berechnet ! // v.0.1.3 WiFi ESSID / MAC werden ausgelesen ! // v.0.1.2 Playlists ! // v.0.1.1 History ! // v.0.1.0 erste brauchbare Version ! // ---------------------------------------------------------------------------------------------------- ! // Settings: ! // ---------------------------------------------------------------------------------------------------- ! // Loglevel kann folgenden Wert haben: debug, info, warn, error, none ! var logLevel = 'info'; ! // true: Datenpunkte werden überschrieben (wenn z.B. Bezeichnungen geändert wurden) ! var forceCreation = true; ! // Pfad im Javascript-Adapter unter dem die Geräte angelegt werden sollen bei "Alexa" wird daraus z.B.: javascript.0.Alexa ! var pfad = "AlexaControl"; ! // Hier die Datenpunkti mit dem Cookie und CSRF aus dem Script von Stefan.Franke ! var idCookie = "javascript.0.productive.alexalogon.cookie"; ! var idCsrf = "javascript.0.productive.alexalogon.csrf"; ! // Einslive - Default Radiostation für den Radio an Button. ! var defaultRadiostation = "s24885"; ! // Jede Minute History auslesen? Wert im üblichen Unix Crontab-Stil ! // Manuell jeder Zeit per Button möglich. ! var updateHistoryScheduler = "* * * * "; ! // Wie oft Playlists automatisch auslesen? Wert im üblichen Unix Crontab-Stil ! // Manuell jeder Zeit per Button möglich. ! var updatePlaylistScheduler = "0 0 * * "; ! // Sollen Geräte gelistet werden, die nicht Kontrolliert werden können? (TV-Stick, etc.) ! // Hier wird dann nur die Gruppe "device" erstellt. "player" und "control" werden nicht erstellt. ! var listNonCotrollable = false; ! // Liste der bekannten Devicetypen, Geräte mit bekannten DeviceType ! // auf das ursprüngliche "anlegen" kann verzichtet werden, da die Capabilities geparst werden. ! // Nur Steuerbare Devices werden mit Steuer-Objekten versehen ! var knownDeviceType = { ! "A3S5BH2HU6VAYF": "Echo Dot 2.Gen", ! "AB72C64C86AW2": "Echo", ! "A7WXQPH584YP": "Echo 2.Gen", ! "A10A33FOX2NUBK": "Echo Spot", ! "A1NL4BVLQ4L3N3": "Echo Show", ! "A15ERDAKK5HQQG": "Sonos", ! "A2E0SNTXJVT7WK": "Fire TV V1", ! "ADVBD696BHNV5": "Fire TV Stick V1", ! "A2LWARUGJLBYEW": "Fire TV Stick V2", ! "A2T0P32DY3F7VB": "echosim.io", ! "AILBSA2LNTOYL": "reverb App", ! "A2M35JJZWCQOMZ": "Echo Plus" ! }; ! // ---------------------------------------------------------------------------------------------------- ! // Skript, ab hier nichts ändern ! // ---------------------------------------------------------------------------------------------------- ! // Initiale Variablen setzen ! // ------------------------------------------------------ ! //Script von Stefan.Franke nötig, welches csrf und cookie ausliest ! var csrf = getState(idCsrf).val; ! var cookie = getState(idCookie).val; ! cookie = cookie.replace(/\/g, ""); ! // Object-Pfad definieren unter dem Devices angelegt werden ! var deviceObjectPath = pfad + ".Devices."; ! // Node Module https verwenden ! var https = require('https'); ! // CUSTOMERID wird später aus der Geräteliste ausgelesen ! var mediaOwnerCustomerId; ! // globales Objekt mit allen Devices ! var devices = {}; ! // LoglevelInt defniniern und dann Wert aus den Settings setzen ! var logLevelInt = 5; ! setLoglevel(logLevel); ! // Beim Programmende eine Info ausgeben ! onStop(function skriptStop () { ! logInfo("** AlexaControl wurde gestoppt "); ! }, 2000 /ms/); ! // Das eigentliche Programm läuft ab hier ! // ------------------------------------------------------ ! logInfo(" AlexaControl wurde gestartet "); ! if(forceCreation) { ! logWarn("Forcecreation ist eingeschaltet. Wenn nicht mehr benötigt, bitte im Skript auf false setzen"); ! } ! // Objekte auslegen und anlegen ! initAlexa(); ! // updates History ! schedule(updateHistoryScheduler, function () {rescanHistory();}); ! // updates Playlists ! schedule(updatePlaylistScheduler, function () {updatePlaylists();}); ! // ------------------------------------------------------------------------------------------------------- ! // Objekte Auslesen ! // ------------------------------------------------------------------------------------------------------- ! / ! * liest per https-GET die aktuellen Playlists von Amazon ein und speichert diese in die "Playlists.X" States ! / ! function updatePlaylists() { ! logInfo('[updatePlaylists]'); ! // zur Abfrage wird der erste Echo mit MusicPlayer verwendet ! var echoWithMusicPlayer = getEchoWithMusicPlayerFromDevices(); ! var path = '/api/cloudplayer/playlists?deviceSerialNumber=' + echoWithMusicPlayer.serialNumber + '&deviceType=' + echoWithMusicPlayer.deviceType + '&mediaOwnerCustomerId=' + mediaOwnerCustomerId; ! httpsReqGet( ! path, ! function (result) { ! tmpListe = JSON.parse(result).playlists; ! var playlistsJSON = []; ! var playlistsTitles = []; ! var playlistsIDs = []; ! for (playlist in tmpListe) { ! var obj = { ! "title": tmpListe[playlist][0].title, ! "playlistId": tmpListe[playlist][0].playlistId ! }; ! playlistsJSON.push(obj); ! playlistsTitles.push(tmpListe[playlist][0].title); ! playlistsIDs.push(tmpListe[playlist][0].playlistId); ! } ! setState(pfad + ".Playlists.JSON", JSON.stringify(playlistsJSON)); ! setState(pfad + ".Playlists.Titles", playlistsTitles.join(';')); ! setState(pfad + ".Playlists.IDs", playlistsIDs.join(';')); ! } ! ); ! } ! / ! * liest per https-GET die letzten 20 Alexa-History-Einträge von Amazon ein und speichert diese in die "Playlists.X" States ! / ! function rescanHistory() { ! logInfo('[rescanHistory]'); ! var path = 'https://alexa.amazon.de/api/activities? … 0&offset=1'; ! httpsReqGet( ! path, ! function (result) { ! activities = JSON.parse(result).activities; ! creationTime = getState(pfad + ".History.creationTime").val; ! for(var i = (activities.length - 1); i > 0; i--) { ! if ((activities__.creationTimestamp > creationTime) || creationTime === null) { ! deviceName = getDeviceNameBySerialNumber(activities__.sourceDeviceIds[0].serialNumber); ! setState(pfad + ".History.creationTime", activities__.creationTimestamp); ! setState(pfad + ".History.deviceName", deviceName); ! setState(pfad + ".History.summary", JSON.parse(activities__.description).summary); ! } ! } ! } ! ); ! } ! / ! * Updated ein Device per DatenpunktName, sowohl "control", als auch "player" wird ! * abgerufen und gespeichert befindet sich currentState im Modus "PLAYING", so wird ! * mit einem Timeout diese Funktion für das Device erneut aufgerufen ! * ! * @param string deviceDpName ! / ! function updateDevice(deviceDpName){ ! if(typeof(devices[deviceDpName]) != "undefined") { ! if (deviceIsControllable(devices[deviceDpName].capabilities)) { ! logInfo('[updateDevice] ' + deviceDpName); ! var controlPath = deviceObjectPath + clearName(deviceDpName) + ".control"; ! // deviceObjectPath + clearName(deviceDpName) + ".control.lastState" ! getDeviceStateBySerialAndType(devices[deviceDpName].serialNumber, devices[deviceDpName].deviceType, function(deviceState){ ! // nur updaten, wenn unterschiedlich ! if (deviceState.volume != getState(controlPath + ".volume").val) { ! setState(controlPath + ".volume", parseInt(deviceState.volume)); ! } ! if(deviceHasMusicPlayer(devices[deviceDpName].capabilities)){ ! if (deviceState.shuffling != getState(controlPath + ".shuffle").val) { ! setState(controlPath + ".shuffle", deviceState.shuffling); ! } ! if (deviceState.looping != getState(controlPath + ".repeat").val) { ! setState(controlPath + ".repeat", deviceState.looping); ! } ! } ! getDevicePlayerBySerialAndType(devices[deviceDpName].serialNumber, devices[deviceDpName].deviceType, function(devicePlayer){ ! // player ! var playerPath = deviceObjectPath + clearName(deviceDpName) + ".player"; ! setState(playerPath + ".contentType", getStringOrEmpty(deviceState.contentType)); ! setState(playerPath + ".currentState", getStringOrEmpty(deviceState.currentState)); ! setState(playerPath + ".imageURL", getStringOrEmpty(deviceState.imageURL)); ! setState(playerPath + ".muted", deviceState.muted); ! setState(playerPath + ".providerId", getStringOrEmpty(deviceState.providerId)); ! setState(playerPath + ".radioStationId", getStringOrEmpty(deviceState.radioStationId)); ! setState(playerPath + ".service", getStringOrEmpty(deviceState.service)); ! var providerName = ''; ! if ((devicePlayer !== undefined) && ("provider" in devicePlayer) && (devicePlayer.provider !== null)){ ! providerName = getStringOrEmpty(devicePlayer.provider.providerName); ! } ! setState(playerPath + ".providerName", providerName); ! var title = ''; ! var interpreter = ''; ! var album = ''; ! if ((devicePlayer !== undefined) &&("infoText" in devicePlayer) && (devicePlayer.infoText !== null)){ ! title = getStringOrEmpty(devicePlayer.infoText.title); ! interpreter = getStringOrEmpty(devicePlayer.infoText.subText1); ! album = getStringOrEmpty(devicePlayer.infoText.subText2); ! } ! setState(playerPath + ".title", title); ! setState(playerPath + ".interpreter", interpreter); ! setState(playerPath + ".album", album); ! var mainArtUrl = ''; ! if ((devicePlayer !== undefined) &&("mainArt" in devicePlayer) && (devicePlayer.mainArt !== null)){ ! mainArtUrl = getStringOrEmpty(devicePlayer.mainArt.url); ! } ! setState(playerPath + ".mainArtUrl", mainArtUrl); ! var miniArtUrl = ''; ! if ((devicePlayer !== undefined) &&("miniArt" in devicePlayer) && (devicePlayer.miniArt !== null)){ ! miniArtUrl = getStringOrEmpty(devicePlayer.miniArt.url); ! } ! setState(playerPath + ".miniArtUrl", miniArtUrl); ! var mediaLength = 0; ! var mediaProgress = 0; ! var mediaProgressPercent = 0; ! if ((devicePlayer !== undefined) &&("progress" in devicePlayer) && (devicePlayer.progress !== null)){ ! mediaLength = parseInt(devicePlayer.progress.mediaLength); ! mediaProgress = parseInt(devicePlayer.progress.mediaProgress); ! if (mediaLength > 0) { ! mediaProgressPercent = Math.round(((mediaProgress * 100) / mediaLength)); ! } ! } ! setState(playerPath + ".mediaLength", mediaLength); ! setState(playerPath + ".mediaLengthStr", sekToHMS(mediaLength)); ! setState(playerPath + ".mediaProgress", mediaProgress); ! setState(playerPath + ".mediaProgressStr", sekToHMS(mediaProgress)); ! setState(playerPath + ".mediaProgressPercent", mediaProgressPercent); ! }); ! }); ! } else { ! logInfo('[updateDevice] Device not controllable: ' + deviceDpName); ! } ! }else { ! logInfo('[updateDevice] Device unknown: ' + deviceDpName); ! } ! } ! /* ! * Inkrementiert "mediaProgress" alle 2 Sekunden um 2. So wird ein permanentes https-get überflüssig ! * ruft sich nach 2 Sekunden erneut selbst auf, wenn "currentState" noch auf "PLAYING" steht. ! * ist "mediaProgress" größer als "mediaLength", so ist der Song zu Ende und "updateDevice" wird aufgerufen. ! * ! * @param string deviceDpName ! / ! function updateMediaProgress(deviceDpName) { ! var playerPath = deviceObjectPath + deviceDpName + ".player"; ! var currentState = getState(playerPath + ".currentState").val; ! var mediaProgress = getState(playerPath + ".mediaProgress").val; ! var mediaLength = getState(playerPath + ".mediaLength").val; ! if ((currentState == 'PLAYING') ) { ! mediaProgressNew = mediaProgress + 2; ! // Am Ende des Titels soll neu geladen werden. Ist es Radio (länge = 0) dann alle 200 sekunden ! if ((mediaProgressNew > mediaLength) && ((mediaLength > 0) || (mediaProgressNew % 200 < 2))){ ! setTimeout( function() { updateDevice(deviceDpName); }, 2000 ); ! } ! // Nun mediaProgress und mediaProgressPercent neu berechnen ! if (mediaLength > 0) { ! mediaProgressPercent = Math.round((((mediaProgressNew) * 100) / mediaLength)); ! } else { ! mediaProgressPercent = 0; ! } ! setState(playerPath + ".mediaProgressPercent", mediaProgressPercent); ! setState(playerPath + ".mediaProgress", mediaProgressNew); ! setState(playerPath + ".mediaProgressStr", sekToHMS(mediaProgressNew)); ! setTimeout( function() { updateMediaProgress(deviceDpName); }, 2000 ); ! } ! } ! /* ! * Ruft den aktuellen State eines Devices per Seriennummer und Type von Amazon ab. ! * Gibt die Antwort an "callback(result)" weiter ! * ! * @param string serialNumber ! * @param string deviceType ! * @param function callback ! / ! function getDeviceStateBySerialAndType(serialNumber, deviceType, callback) { ! httpsReqGet( ! '/api/media/state?deviceSerialNumber=' + serialNumber + '&deviceType=' + deviceType, ! function(result) { ! // Es kommt vor, dass Geräte nicht antworten, weil sie nicht aktiv sind. Dann greift hier der Dummy-Wert ! if (result == '{"message":null}') { ! result = JSON.stringify({ ! "clientId":null, ! "contentId":null, ! "contentType":null, ! "currentState":"IDLE", ! "imageURL":null, ! "isDisliked":false, ! "isLiked":false, ! "looping":false, ! "mediaOwnerCustomerId":null, ! "muted":false, ! "programId":null, ! "progressSeconds":0, ! "providerId":null, ! "queue":null, ! "queueId":null, ! "queueSize":0, ! "radioStationId":null, ! "radioVariety":0, ! "referenceId":null, ! "service":null, ! "shuffling":false, ! "timeLastShuffled":0, ! "volume":0 ! }); ! } ! if(callback !== undefined && typeof callback === 'function') callback(JSON.parse(result)); ! } ! ); ! } ! /* ! * Ruft den aktuellen State eines Devices per DatenpunktNamen von Amazon ab. ! * Gibt die Antwort an "callback(result)" weiter ! * ! * @param string deviceDpName ! * @param function callback ! / ! function getDeviceState(deviceDpName, callback) { ! getDeviceStateBySerialAndType(devices[deviceDpName].serialNumber, devices[deviceDpName].deviceType, callback); ! } ! /* ! * Ruft die aktuelle PlayerInfo eines Devices per Seriennummer und Type von Amazon ab. ! * Gibt die Antwort an "callback(result)" weiter ! * ! * @param string serialNumber ! * @param string deviceType ! * @param function callback ! / ! function getDevicePlayerBySerialAndType(serialNumber, deviceType, callback) { ! httpsReqGet( ! '/api/np/player?deviceSerialNumber=' + serialNumber + '&deviceType=' + deviceType, ! function(result) { ! // Es kommt vor, dass Geräte nicht antworten, weil sie nicht aktiv sind. Dann greift hier der Dummy-Wert ! if (result == '{"message":null}') { ! result = JSON.stringify({ ! "playerInfo":{ ! "hint":null, ! "infoText":null, ! "isPlayingInLemur":false, ! "lemurVolume":null, ! "lyrics":null, ! "mainArt":null, ! "mediaId":null, ! "miniArt":null, ! "miniInfoText":null, ! "playbackSource":null, ! "playingInLemurId":null, ! "progress":null, ! "provider":null, ! "queueId":null, ! "state":null, ! "template":null, ! "transport":null, ! "volume":null ! } ! }); ! } ! if(callback !== undefined && typeof callback === 'function') callback(JSON.parse(result).playerInfo); ! } ! ); ! } ! /* ! * Ruft die aktuelle PlayerInfo eines Devices per DatenpunktNamen von Amazon ab. ! * Gibt die Antwort an "callback(result)" weiter ! * ! * @param string deviceDpName ! * @param function callback ! / ! function getDevicePlayer(deviceDpName, callback) { ! getDevicePlayerBySerialAndType(devices[deviceDpName].serialNumber, devices[deviceDpName].deviceType, callback); ! } ! /* ! * liest per https-GET alle Alexa-fähigen Geräte neu ein und updated bei allen ! * bereits bekannten Geräten die Infos, wie z.B. Onlinestatus, WLAN, etc. ! / ! function updateAlexa(){ ! logInfo('[updateAlexa]'); ! httpsReqGet('/api/devices/device', function(result) { ! // Falls Result leer ist, soll nichts weiter gemacht werden ! if(!result) return logWarn("Es konnten keine Daten ermittelt werden! Cookie richtig?"); ! logDebug(result); ! var alexaDeviceObj = JSON.parse(result); ! var numberOfDevices = alexaDeviceObj.devices.length; ! logInfo("Anzahl vorhandener Geräte mit Alexa Unterstützung: " + numberOfDevices); ! if (numberOfDevices < 1) { ! return logWarn("Error: Skript konnte keine Geräte abfragen"); ! } ! // Kundenindiviuelle Customer ID aus dem ersten Gerät entnehmen -> in vorbereitete globale Variable schreiben ! mediaOwnerCustomerId = getStringOrEmpty(alexaDeviceObj.devices[0].deviceOwnerCustomerId); ! // Devices ! for(var i = 0; i < numberOfDevices; i++) { ! // Nur bekannte Geraete updaten ! if(typeof(devices[clearName(alexaDeviceObj.devices_[i].accountName)]) != "undefined") { ! // Pruefen, ob das Geraet noch das selbe ist ! if (devices[clearName(alexaDeviceObj.devices_[i].accountName)].serialNumber != alexaDeviceObj.devices__.serialNumber){ ! logError('Das Geraet "' + clearName(alexaDeviceObj.devices__.accountName) + '" hat nach update eine andere Seriennummer!'); ! } else { ! var devicePath = deviceObjectPath + clearName(alexaDeviceObj.devices__.accountName) + ".device"; ! httpsReqGet( ! '/api/device-wifi-details?deviceSerialNumber=' + alexaDeviceObj.devices__.serialNumber + '&deviceType=' + alexaDeviceObj.devices_.deviceType, ! function(result) { ! setState(devicePath + ".essid", getStringOrEmpty(JSON.parse(result).essid)); ! setState(devicePath + ".macAddress", getStringOrEmpty(JSON.parse(result).macAddress)); ! } ! ); ! setState(devicePath + ".language", getStringOrEmpty(alexaDeviceObj.devices_.language)); ! setState(devicePath + ".online", alexaDeviceObj.devices_.online); ! setState(devicePath + ".parentClusters", getStringOrEmpty(alexaDeviceObj.devices_.parentClusters)); ! setState(devicePath + ".softwareVersion", getStringOrEmpty(alexaDeviceObj.devices_.softwareVersion)); ! // Device updaten ! updateDevice(clearName(alexaDeviceObj.devices_.accountName)); ! } ! } ! } ! }); ! } ! // –----------------------------------------------------------------------------------------------------- ! // Objekte Anlegen ! // ------------------------------------------------------------------------------------------------------- ! /* ! * liest per https-GET alle Alexa-fähigen Geräte ein und legt die Objekte an ! / ! function initAlexa() { ! httpsReqGet('/api/devices/device', function(result) { ! // Falls Result leer ist, soll nichts weiter gemacht werden ! if(!result) return logWarn("Es konnten keine Daten ermittelt werden! Cookie richtig?"); ! logDebug(result); ! var alexaDeviceObj = JSON.parse(result); ! var numberOfDevices = alexaDeviceObj.devices.length; ! logInfo("Anzahl vorhandener Geräte mit Alexa Unterstützung: " + numberOfDevices); ! if (numberOfDevices < 1) { ! return logWarn("Error: Skript konnte keine Geräte abfragen"); ! } ! // Kundenindiviuelle Customer ID aus dem ersten Gerät entnehmen -> in vorbereitete globale Variable schreiben ! mediaOwnerCustomerId = alexaDeviceObj.devices[0].deviceOwnerCustomerId; ! createDeviceState(pfad + ".mediaOwnerCustomerId", mediaOwnerCustomerId, forceCreation, {name:"Individuelle Kunden ID", type:"string", role:"value"}); ! // Devices ! for(var i = 0; i < numberOfDevices; i++) { ! if (listNonCotrollable || deviceIsControllable(alexaDeviceObj.devices_.capabilities)) { ! devices[clearName(alexaDeviceObj.devices[i].accountName)] = createDevice(alexaDeviceObj.devices_, forceCreation); ! } ! } ! // Update ! createState( ! pfad + ".update", ! false, ! forceCreation, ! {name:"Update Devices", type:"boolean", role:"button"}, ! null, ! function () { ! setTimeout( ! function() { ! logInfo("CreateON: " + pfad + ".update"); ! on({id: "javascript." + instance + "." + pfad + ".update", change: "any"}, ! function (obj){ ! unsetButtonFirst(obj, function (obj) {updateAlexa();}); ! }) ! } ! , ! 3000 ! ); ! } ! ); ! // Playlists ! createDeviceState(pfad + ".Playlists.JSON", null, forceCreation, {name:"Playlists als JSON", type:"string", role:"state"}); ! createDeviceState(pfad + ".Playlists.Titles", null, forceCreation, {name:"Playlist Titel als Liste fuer Dropdown", type:"string", role:"state"}); ! createDeviceState(pfad + ".Playlists.IDs", null, forceCreation, {name:"Playlist IDs als Liste fuer Dropdown", type:"string", role:"state"}); ! createState( ! pfad + ".Playlists.update", ! false, ! forceCreation, ! {name:"Update Playlists", type:"boolean", role:"button"}, ! null, ! function () { ! setTimeout( ! function() { ! logInfo("CreateON: " + pfad + ".Playlists.update"); ! on({id: "javascript." + instance + "." + pfad + ".Playlists.update", change: "any"}, ! function (obj){ ! unsetButtonFirst(obj, function (obj) {updatePlaylists();}); ! }) ! } ! , ! 3000 ! ); ! } ! ); ! // Einmalig die Playlists abfragen ! updatePlaylists(); ! // History ! createState(pfad + ".History.creationTime", null, forceCreation, {name:"Timestamp", type:"number", role:"state"}); ! createState(pfad + ".History.deviceName", null, forceCreation, {name:"deviceName", type:"string", role:"state"}); ! createState(pfad + ".History.summary", null, forceCreation, {name:"summary", type:"string", role:"state"}); ! createState( ! pfad + ".History.update", ! false, ! forceCreation, ! {name:"Update History", type:"boolean", role:"button"}, ! null, ! function () { ! setTimeout( ! function() { ! logInfo("CreateON: " + pfad + ".History.update"); ! on({id: "javascript." + instance + "." + pfad + ".History.update", change: "any"}, ! function (obj){ ! unsetButtonFirst(obj, function (obj) {rescanHistory();}); ! }) ! } ! , ! 3000 ! ); ! } ! ); ! // Erstmalig die History abgragen ! rescanHistory(); ! }); ! } ! /* ! * Erzeugt alle States zu einem übergebenen Device-Objekt. Anhand der "capabilities" ! * des Devices, werden, ggf. "control" und "player" States erstellt. ! * ! * @param object amazonDeviceObject ! * @param boolean forceCreation ! / ! function createDevice(amazonDeviceObject, forceCreation) { ! logInfo('createDevice: '+ amazonDeviceObject.accountName); ! var devicePath = deviceObjectPath + clearName(amazonDeviceObject.accountName) + ".device"; ! // device ! createDeviceState(devicePath + ".accountName", getStringOrEmpty(amazonDeviceObject.accountName), forceCreation, {name:"Name", type:"string", role:"value"}); ! createDeviceState(devicePath + ".capabilities", getStringOrEmpty(JSON.stringify(amazonDeviceObject.capabilities)), forceCreation, {name:"Fähigkeiten", type:"string", role:"value"}); ! createDeviceState(devicePath + ".clusterMembers", getStringOrEmpty(JSON.stringify(amazonDeviceObject.clusterMembers)), forceCreation, {name:"GruppenMitglieder", type:"string", role:"value"}); ! createDeviceState(devicePath + ".deviceAccountId", getStringOrEmpty(amazonDeviceObject.deviceAccountId), forceCreation, {name:"AccountId", type:"string", role:"value"}); ! createDeviceState(devicePath + ".deviceFamily", getStringOrEmpty(amazonDeviceObject.deviceFamily), forceCreation, {name:"DeviceFamily", type:"string", role:"value"}); ! createDeviceState(devicePath + ".deviceOwnerCustomerId", getStringOrEmpty(amazonDeviceObject.deviceOwnerCustomerId), forceCreation, {name:"deviceOwnerCustomerId", type:"string", role:"value"}); ! createDeviceState(devicePath + ".deviceType", getStringOrEmpty(amazonDeviceObject.deviceType), forceCreation, {name:"deviceType", type:"string", role:"value"}); ! createDeviceState(devicePath + ".deviceTypeString", getStringOrEmpty(deviceTypeStr(amazonDeviceObject.deviceType)), forceCreation, {name:"deviceType als String", type:"string", role:"value"}); ! createDeviceState(devicePath + ".deviceTypeFriendlyName", getStringOrEmpty(amazonDeviceObject.deviceTypeFriendlyName), forceCreation, {name:"deviceTypeFriendlyName", type:"string", role:"value"}); ! httpsReqGet( ! '/api/device-wifi-details?deviceSerialNumber=' + amazonDeviceObject.serialNumber + '&deviceType=' + amazonDeviceObject.deviceType, ! function(result) { ! createDeviceState(devicePath + ".essid", getStringOrEmpty(JSON.parse(result).essid), forceCreation, {name:"essid", type:"string", role:"value"}); ! createDeviceState(devicePath + ".macAddress", getStringOrEmpty(JSON.parse(result).macAddress), forceCreation, {name:"macAddress", type:"string", role:"value"}); ! } ! ); ! createDeviceState(devicePath + ".language", getStringOrEmpty(amazonDeviceObject.language), forceCreation, {name:"language", type:"string", role:"value"}); ! createDeviceState(devicePath + ".online", amazonDeviceObject.online, forceCreation, {name:"online (Klappt nur bei ECHOs)", type:"boolean", role:"value"}); ! createDeviceState(devicePath + ".parentClusters", getStringOrEmpty(amazonDeviceObject.parentClusters), forceCreation, {name:"Mitglied in dieser Gruppe", type:"string", role:"value"}); ! createDeviceState(devicePath + ".serialNumber", getStringOrEmpty(amazonDeviceObject.serialNumber), forceCreation, {name:"serialNumber", type:"string", role:"value"}); ! createDeviceState(devicePath + ".softwareVersion", getStringOrEmpty(amazonDeviceObject.softwareVersion), forceCreation, {name:"softwareVersion", type:"string", role:"value"}); ! if (deviceIsControllable(amazonDeviceObject.capabilities)) { ! createDeviceControl(amazonDeviceObject, forceCreation); ! } ! return { ! 'serialNumber' : amazonDeviceObject.serialNumber, ! 'deviceType' : amazonDeviceObject.deviceType, ! 'capabilities' : amazonDeviceObject.capabilities ! }; ! } ! /* ! * Erzeugt alle "control" und "player" States zu einem übergebenen Device-Objekt. ! * Für Initial-Werte wird das Device bei Amazon zunächst abgefragt ! * ! * @param object amazonDeviceObject ! * @param boolean forceCreation ! / ! function createDeviceControl(amazonDeviceObject, forceCreation) { ! logInfo('createDeviceControl: '+ amazonDeviceObject.accountName); ! var controlPath = deviceObjectPath + clearName(amazonDeviceObject.accountName) + ".control"; ! // control ! createDeviceState(controlPath + ".LastStatus", 'INIT', forceCreation, {name:"Letzter Status", type:"string", role:"value"}); ! createDeviceControlState(controlPath + ".updateDevice", false, forceCreation, {name:"Device abfragen", type:"boolean", role:"button"}); ! // deviceObjectPath + clearName(amazonDeviceObject.accountName) + ".control.lastState" ! getDeviceStateBySerialAndType(amazonDeviceObject.serialNumber, amazonDeviceObject.deviceType, function(deviceState){ ! createDeviceControlState(controlPath + ".volume", parseInt(deviceState.volume), forceCreation, {name:"Volume in Prozent(0-100)", type:"number", role:"level.volume"}); ! createDeviceControlState(controlPath + ".pause", false, forceCreation, {name:"Pause", type:"boolean", role:"button"}); ! createDeviceControlState(controlPath + ".play", false, forceCreation, {name:"Play", type:"boolean", role:"button"}); ! if(deviceHasMusicPlayer(amazonDeviceObject.capabilities)){ ! createDeviceControlState(controlPath + ".next", false, forceCreation, {name:"Next (nächster Titel)", type:"boolean", role:"button"}); ! createDeviceControlState(controlPath + ".previous", false, forceCreation, {name:"Previous (vorheriger Titel)", type:"boolean", role:"button"}); ! createDeviceControlState(controlPath + ".forward", false, forceCreation, {name:"Forward (Hörbuch 30 Sekunden vor)", type:"boolean", role:"button"}); ! createDeviceControlState(controlPath + ".rewind", false, forceCreation, {name:"Rewind (Hörbuch 30 Sekunden zurück)", type:"boolean", role:"button"}); ! createDeviceControlState(controlPath + ".previous", false, forceCreation, {name:"Previous (vorheriger Titel)", type:"boolean", role:"button"}); ! createDeviceControlState(controlPath + ".shuffle", deviceState.shuffling, forceCreation, {name:"Shuffel an/aus", type:"boolean", role:"switch"}); ! createDeviceControlState(controlPath + ".repeat", deviceState.looping, forceCreation, {name:"Repeat an/aus)", type:"boolean", role:"switch"}); ! createDeviceControlState(controlPath + ".playlistId", false, forceCreation, {name:"spiele Playlist", type:"string", role:"control.value"}); ! } ! if(deviceHasTuneIn(amazonDeviceObject.capabilities)){ ! createDeviceControlState(controlPath + ".radio", false, forceCreation, {name:"Letzte Radiostation an/aus", type:"boolean", role:"switch"}); ! createDeviceControlState(controlPath + ".tunein", defaultRadiostation, forceCreation, {name:"tunein Radiosenderkennung", type:"string", role:"control.value"}); ! } ! getDevicePlayerBySerialAndType(amazonDeviceObject.serialNumber, amazonDeviceObject.deviceType, function(devicePlayer){ ! // player ! var playerPath = deviceObjectPath + clearName(amazonDeviceObject.accountName) + ".player"; ! createDeviceState(playerPath + ".contentType", getStringOrEmpty(deviceState.contentType), forceCreation, {name:"contentType", type:"string", role:"value"}); // "LIVE_STATION" | "TRACKS" | "CUSTOM_STATION" ! createDeviceControlState(playerPath + ".currentState", getStringOrEmpty(deviceState.currentState), forceCreation, {name:"currentState", type:"string", role:"value"}); // "PAUSED" | "PLAYING" ! createDeviceState(playerPath + ".imageURL", getStringOrEmpty(deviceState.imageURL), forceCreation, {name:"Grosses Bild", type:"string", role:"value"}); ! createDeviceState(playerPath + ".muted", deviceState.muted, forceCreation, {name:"muted", type:"boolean", role:"value"}); ! createDeviceState(playerPath + ".providerId", getStringOrEmpty(deviceState.providerId), forceCreation, {name:"providerId", type:"string", role:"value"}); // "TUNE_IN" | "CLOUD_PLAYER" | "ROBIN" ! createDeviceState(playerPath + ".radioStationId", getStringOrEmpty(deviceState.radioStationId), forceCreation, {name:"radioStationId", type:"string", role:"value"}); // "s24885" | null ! createDeviceState(playerPath + ".service", getStringOrEmpty(deviceState.service), forceCreation, {name:"service", type:"string", role:"value"}); // "TUNE_IN" | "CLOUD_PLAYER" | "PRIME_STATION" ! var providerName = null; ! if ((devicePlayer !== undefined) &&("provider" in devicePlayer) && (devicePlayer.provider !== null)){ ! providerName = getStringOrEmpty(devicePlayer.provider.providerName); ! } ! createDeviceState(playerPath + ".providerName", providerName, forceCreation, {name:"active providerName", type:"string", role:"value"}); // "Amazon Music" | "TuneIn Live-Radio" ! var title = ''; ! var interpreter = ''; ! var album = ''; ! if ((devicePlayer !== undefined) &&("infoText" in devicePlayer) && (devicePlayer.infoText !== null)){ ! title = getStringOrEmpty(devicePlayer.infoText.title); ! interpreter = getStringOrEmpty(devicePlayer.infoText.subText1); ! album = getStringOrEmpty(devicePlayer.infoText.subText2); ! } ! createDeviceState(playerPath + ".title", title, forceCreation, {name:"active title", type:"string", role:"value"}); ! createDeviceState(playerPath + ".interpreter", interpreter, forceCreation, {name:"active interpreter", type:"string", role:"value"}); ! createDeviceState(playerPath + ".album", album, forceCreation, {name:"active album", type:"string", role:"value"}); ! var mainArtUrl = ''; ! if ((devicePlayer !== undefined) &&("mainArt" in devicePlayer) && (devicePlayer.mainArt !== null)){ ! mainArtUrl = getStringOrEmpty(devicePlayer.mainArt.url); ! } ! createDeviceState(playerPath + ".mainArtUrl", mainArtUrl, forceCreation, {name:"active mainArtUrl", type:"string", role:"value"}); ! var miniArtUrl = ''; ! if ((devicePlayer !== undefined) &&("miniArt" in devicePlayer) && (devicePlayer.miniArt !== null)){ ! miniArtUrl = getStringOrEmpty(devicePlayer.miniArt.url); ! } ! createDeviceState(playerPath + ".miniArtUrl", miniArtUrl, forceCreation, {name:"active miniArtUrl", type:"string", role:"value"}); ! var mediaLength = 0; ! var mediaProgress = 0; ! var mediaProgressPercent = 0; ! if ((devicePlayer !== undefined) &&("progress" in devicePlayer) && (devicePlayer.progress !== null)) { ! mediaLength = parseInt(devicePlayer.progress.mediaLength); ! mediaProgress = parseInt(devicePlayer.progress.mediaProgress); ! if (mediaLength > 0) { ! mediaProgressPercent = Math.round(((mediaProgress * 100) / mediaLength)); ! } ! } ! createDeviceState(playerPath + ".mediaLength", mediaLength, forceCreation, {name:"active mediaLength", type:"number", role:"value"}); ! createDeviceState(playerPath + ".mediaLengthStr", sekToHMS(mediaLength), forceCreation, {name:"active mediaLength als (HH:)MM:SS", type:"string", role:"value"}); ! createDeviceState(playerPath + ".mediaProgress", mediaProgress, forceCreation, {name:"active mediaProgress", type:"number", role:"value"}); ! createDeviceState(playerPath + ".mediaProgressStr", sekToHMS(mediaProgress), forceCreation, {name:"active mediaProgress als (HH:)MM:SS", type:"string", role:"value"}); ! createDeviceState(playerPath + ".mediaProgressPercent", mediaProgressPercent, forceCreation, {name:"active mediaProgressPercent", type:"number", role:"value"}); ! }); ! }); ! } ! /* ! * Erzeugt einen State und macht danach einen Logeintrag ! * ! * @param string objectdevicePath ! * @param mixed initialValue ! * @param boolean forceCreation ! * @param object common ! / ! function createDeviceState(objectdevicePath, initialValue, forceCreation, common) { ! createState(objectdevicePath, initialValue, forceCreation, common, null, function(){logInfo('createState: ' + objectdevicePath)}); ! } ! /* ! * Erzeugt einen State und macht danach einen Logeintrag ! * Dann wird für den State eine "on()-Funktion" erzeugt, die die gewünschte Funktion ausfürht ! * ! * @param string objectdevicePath ! * @param mixed initialValue ! * @param boolean forceCreation ! * @param object common ! / ! function createDeviceControlState(objectdevicePath, initialValue, forceCreation, common) { ! createState( ! objectdevicePath, ! initialValue, ! forceCreation, ! common, ! null, ! function () { ! logInfo('createState: ' + objectdevicePath); ! setTimeout( ! function() { ! logInfo("CreateON: " + objectdevicePath); ! on({id: "javascript." + instance + "." + objectdevicePath, change: "any"}, ! function (obj){ ! var objArr = obj.id.match(/(^.+).(.+).(.+).(.+)$/, ""); //Aufteilung in devicePath + deviceDpName + CMD ! var deviceDpName = objArr[2]; ! var cmd = objArr[4]; ! logDebug("Device: " + deviceDpName+", Kommando: " + cmd); ! parameter = obj.state.val; ! var reloadCallback = function() {setTimeout(function() {updateDevice(deviceDpName);}, 3000);}; ! switch (cmd) { ! // Buttons, werden immer wieder auf false gesetzt ! case "updateDevice": ! unsetButtonFirst(obj, function (obj) {updateDevice(deviceDpName);}); ! break; ! case "pause": ! unsetButtonFirst(obj, function (obj) {setPause(deviceDpName, reloadCallback);}); ! break; ! case "play": ! unsetButtonFirst(obj, function (obj) {setPlay(deviceDpName, reloadCallback);}); ! break; ! case "next": ! unsetButtonFirst(obj, function (obj) {setNext(deviceDpName, reloadCallback);}); ! break; ! case "previous": ! unsetButtonFirst(obj, function (obj) {setPrevious(deviceDpName, reloadCallback);}); ! break; ! case "forward": ! unsetButtonFirst(obj, function (obj) {setForward(deviceDpName, reloadCallback);}); ! break; ! case "rewind": ! unsetButtonFirst(obj, function (obj) {setRewind(deviceDpName, reloadCallback);}); ! break; ! //Switch ! case "shuffle": ! if(parameter === null){ ! logWarn("Alexa Shuffle: kein true/false angegeben. Auf true gesetzt."); ! parameter = true; ! } ! setShuffle(deviceDpName, parameter); ! break; ! case "repeat": ! if(parameter === null){ ! logWarn("Alexa Repeat: kein true/false angegeben. Auf true gesetzt."); ! parameter = true; ! } ! setRepeat(deviceDpName, parameter); ! break; ! case "radio": ! if(obj.state.val) { ! // Letzte Radiostation einschlaten ! var stationId = getState(deviceObjectPath + deviceDpName + ".control.tunein").val; ! setTuneIn(deviceDpName,stationId, reloadCallback); ! } else { ! // Musik auf Pause. ! setPause(deviceDpName, reloadCallback); ! } ! break; ! case "volume": ! if(!parameter ||parameter === null){ ! logWarn("Alexa Volume: keine Lautstärke angegeben. Parameter fehlt."); ! break; ! } ! parameter = parseInt(parameter); ! if(parameter < 0) { ! parameter = 0; ! logWarn("Alexa Volume: ungültige Lautsträke angegeben (<0). Auf 0 gesetzt."); ! } ! if(parameter > 100) { ! parameter = 100; ! logWarn("Alexa Volume: ungültige Lautsträke angegeben (>100). Auf 100 gesetzt."); ! } ! setVolume(deviceDpName, parameter); ! break; ! case "playlistId": ! setPlaylistId(deviceDpName, parameter, reloadCallback); ! break; ! case "tunein": ! setTuneIn(deviceDpName,parameter, reloadCallback); ! break; ! case "currentState": ! // den aktuellen "mediaProgress" berechnen, statt ihn immer neu runterzuladen ! if ((obj.oldState.val == 'PAUSED') && (obj.state.val == 'PLAYING')) { ! // Wechsel von Pause zu Playing ! updateMediaProgress(deviceDpName); ! } else if (obj.state.val == 'PLAYING') { ! // war vorher nicht Pause, nun aber Playing, dann überprüfen, ob sich "mediaProgress" ! // innerhalb einer gewissen Zeit verändert (dann wurde die Funktion bereits ausgeführt) ! var playerPath = deviceObjectPath + deviceDpName + ".player"; ! setTimeout( function() { ! var mediaProgress = getState(playerPath + ".mediaProgress").val; ! setTimeout( function() { ! var mediaProgressNew = getState(playerPath + ".mediaProgress").val; ! // Wurde mediaProgress in der Zeit trotz PLAYING nicht verändert, dann trotzdem ausführen ! if (mediaProgressNew == mediaProgress){ ! setState(playerPath + ".mediaProgress", mediaProgressNew + 7); ! updateMediaProgress(deviceDpName); ! } ! }, 5000 ); ! }, 3000 ); ! } ! break; ! default: ! logWarn("Kommando << "+cmd+" >> im Skript nicht behandelt"); ! break; ! } ! }) ! } ! , ! 3000 ! ); ! } ! ); ! } ! // –----------------------------------------------------------------------------------------------------- ! // HTTPS-GET/POST-Funktionen ! // ------------------------------------------------------------------------------------------------------- ! /* ! * Setzt die Options für den https Request ! * ! * @param string path ! * @param string method - Should be GET oder POST ! / ! function setOptions(path,method) { ! var options = { ! "host": 'layla.amazon.de', ! "path": path, ! "method": method, ! "timeout":10000, ! "headers": { ! 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36', ! 'Content-Type': 'text/plain', ! 'csrf' : csrf, ! 'Cookie' : cookie ! } ! }; ! return options; ! } ! /* ! * Erzeugt eine GET Anfrage ! * @param string path ! * @param function callback ! / ! function httpsReqGet(path,callback) { ! logDebug("Abfrage " + path + " an Alexa gesendet"); ! var options = setOptions(path,"GET"); ! var req = https.get(options, function getDevices(res) { ! logDebug('STATUS: ' + res.statusCode) + ": " + statusCode(res.statusCode); // Statuscode ! logDebug('HEADERS: ' + JSON.stringify(res.headers)); // Header (Rückmeldung vom Webserver) ! // Buffer the body entirely for processing as a whole. ! var bodyChunks = []; ! var chunkLine = 0; ! res.on('data', function(chunk) { ! chunkLine = chunkLine + 1; ! // Hier können die einzelnen Zeilen verarbeitet werden... ! logDebug("Zeilennummer: " + chunkLine+ " ,Inhalt: " + chunk); ! bodyChunks.push(chunk); ! }).on('end', function() { ! logDebug("ARRAY mit den einzelnen Zeilen: " + bodyChunks); ! logDebug("ARRAY Länge: " + bodyChunks.length); ! var body = Buffer.concat(bodyChunks); ! // ...und/oder das Gesamtergebnis (body). ! if(!body) log("keine Daten erhalten","warn"); ! logDebug('BODY: ' + body); ! if(callback !== undefined && typeof callback === 'function') return callback(body); ! }); ! }); ! req.on('error', function(e) { // Fehler abfangen ! log('ERROR: ' + e.message,"warn"); ! log("keinen gültigen Callback gefunden","warn"); ! ok = false; ! }); ! req.end(); ! } ! /* ! * Setzt das Device auf die Lautstärke ! * ! * @param string deviceDpName ! * @param integer volumeLevel ! * @param function callback ! / ! function setVolume(deviceDpName, volumeLevel, callback) {httpsPostCmd(deviceDpName, '{"type":"VolumeLevelCommand","volumeLevel":' + volumeLevel + '}' , callback);} ! /* ! * Setzt das Device auf PLAY ! * ! * @param string deviceDpName ! * @param function callback ! / ! function setPlay(deviceDpName, callback) {httpsPostCmd(deviceDpName, '{"type":"PlayCommand"}', callback);} ! /* ! * Setzt das Device auf PAUSE ! * ! * @param string deviceDpName ! * @param function callback ! / ! function setPause(deviceDpName, callback) {httpsPostCmd(deviceDpName, '{"type":"PauseCommand"}', callback);} ! /* ! * Setzt das Device auf NEXT ! * ! * @param string deviceDpName ! * @param function callback ! / ! function setNext(deviceDpName, callback) {httpsPostCmd(deviceDpName, '{"type":"NextCommand"}', callback);} ! /* ! * Setzt das Device auf PREVIOUS ! * ! * @param string deviceDpName ! * @param function callback ! / ! function setPrevious(deviceDpName, callback) {httpsPostCmd(deviceDpName, '{"type":"PreviousCommand"}', callback);} ! /* ! * Setzt das Device auf FORWARD ! * ! * @param string deviceDpName ! * @param function callback ! / ! function setForward(deviceDpName, callback) {httpsPostCmd(deviceDpName, '{"type":"ForwardCommand"}', callback);} ! /* ! * Setzt das Device auf REWIND ! * ! * @param string deviceDpName ! * @param function callback ! / ! function setRewind(deviceDpName, callback) {httpsPostCmd(deviceDpName, '{"type":"RewindCommand"}', callback);} ! /* ! * Setzt für das Device SHUFFLE auf den gewünschten zustand ! * ! * @param string deviceDpName ! * @param boolean state ! * @param function callback ! / ! function setShuffle(deviceDpName, state, callback) {httpsPostCmd(deviceDpName, '{"type":"ShuffleCommand","shuffle":' + state + '}', callback);} ! /* ! * Setzt für das Device REPEAT auf den gewünschten zustand ! * ! * @param string deviceDpName ! * @param boolean state ! * @param function callback ! / ! function setRepeat(deviceDpName, state, callback) {httpsPostCmd(deviceDpName, '{"type":"RepeatCommand","repeat":' + state + '}', callback);} ! /* ! * Schickt ein Kommando an Alexa ! * ! * @param string deviceDpName ! * @param string postData ! * @param function callback ! / ! function httpsPostCmd(deviceDpName, postData, callback) { ! logInfo("[httpsPostCmd] Device: " + deviceDpName + " - Kommando: " + postData); ! var path = '/api/np/command?' ! + 'deviceSerialNumber=' + devices[deviceDpName].serialNumber ! + '&deviceType=' + devices[deviceDpName].deviceType ; ! httpsPost(deviceDpName, path, postData, callback); ! } ! /* ! * Startet auf dem Device den Radiosender ! * ! * @param string deviceDpName ! * @param string stationId ! * @param function callback ! / ! function setTuneIn(deviceDpName,stationId, callback) { ! logInfo("[setTuneIn] Device: " + deviceDpName + " - TuneIn-StationId: " + stationId); ! var path = '/api/tunein/queue-and-play?' ! + 'deviceSerialNumber=' + devices[deviceDpName].serialNumber ! + '&deviceType=' + devices[deviceDpName].deviceType ! + '&guideId=' + stationId ! + '&contentType=station&callSign=&mediaOwnerCustomerId=' + mediaOwnerCustomerId; ! httpsPost(deviceDpName, path, '', callback); ! } ! /* ! * Startet auf dem Device die Playlist ! * ! * @param string deviceDpName ! * @param string playlistId ! * @param function callback ! / ! function setPlaylistId(deviceDpName, playlistId, callback) { ! logInfo("[setPlaylistId] Device: " + deviceDpName + " - PlaylistId: " + playlistId); ! var path = '/api/cloudplayer/queue-and-play?' ! + 'deviceSerialNumber=' + devices[deviceDpName].serialNumber ! + '&deviceType=' + devices[deviceDpName].deviceType ! + '&shuffle=false' ! + '&contentType=station&callSign=&mediaOwnerCustomerId=' + mediaOwnerCustomerId; ! httpsPost(deviceDpName, path, '{"playlistId":"' + playlistId + '"}', callback); ! } ! /* ! * Erzeugt eine POST Anfrage und setzt den Status-Code ! * der Anfrage in das 'control.LastStatus' Feld ! * ! * @param string deviceDpName ! * @param string path ! * @param string postData ! * @param function callback ! / ! function httpsPost(deviceDpName, path, postData, callback) { ! logDebug("[httpsPost] Device: " + deviceDpName + " Path: " + path + " postData: " + postData); ! var options = setOptions(path,"POST"); ! // request object ! var req = https.request(options, function (res) { ! var result = ''; ! res.on('data', function (chunk) { ! result += chunk; ! }); ! res.on('end', function () { ! logDebug(result); ! setState(deviceObjectPath + deviceDpName +".control.LastStatus",res.statusCode.toString()+" " + statusCode(res.statusCode)); ! if(res.statusCode != 200) { ! logWarn("Negative Rückmeldung von Alexa: " + res.statusCode + ": " + statusCode(res.statusCode)); ! logWarn("Gesendetes Kommando: " + postData); ! } else { ! logDebug('STATUS: ' + res.statusCode + ": " + statusCode(res.statusCode)); // Statuscode ! } ! if(res.statusCode != 200){ ! logWarn('HEADERS: ' + JSON.stringify(res.headers)); // Header (Rückmeldung vom Webserver) ! } ! if(callback !== undefined && typeof callback === 'function') callback(result); ! }); ! res.on('error', function (err) { ! logWarn('ERROR: ' + err.message); ! }) ! }); ! // req error ! req.on('error', function (err) { ! logWarn('ERROR: ' + err.message); ! }); ! //send request witht the postData form ! req.write(postData); ! req.end(); ! } ! // –----------------------------------------------------------------------------------------------------- ! // Hilfs-Funktionen ! // ------------------------------------------------------------------------------------------------------- ! /* ! * Setzt das gewünschte Loglevel ! * ! * @param string level ! / ! function setLoglevel(level) { ! switch(level.toLowerCase()) { ! case 'debug': ! logLevelInt = 0; ! break; ! case 'info': ! logLevelInt = 1; ! break; ! case 'warn': ! logLevelInt = 2; ! break; ! case 'error': ! logLevelInt = 3; ! break; ! case 'none': ! logLevelInt = 4; ! break; ! default: ! logLevelInt = 2; ! break; ! } ! } ! /* ! * Logt eine DEBUG Message ! * (wird als info geloggt, da Debug nicht angezeigt wird) ! * ! * @param string msg ! / ! function logDebug(msg) { ! if (logLevelInt <= 0) { ! log(msg, "info"); ! } ! } ! /* ! * Logt eine INFO Message ! * ! * @param string msg ! / ! function logInfo(msg) { ! if (logLevelInt <= 1) { ! log(msg, "info"); ! } ! } ! /* ! * Logt eine WARN Message ! * ! * @param string msg ! / ! function logWarn(msg) { ! if (logLevelInt <= 2) { ! log(msg, "warn"); ! } ! } ! /* ! * Logt eine ERROR Message ! * ! * @param string msg ! / ! function logError(msg) { ! if (logLevelInt <= 3) { ! log(msg, "error"); ! } ! } ! /* ! * Durchsucht ein Array nach needle und ! * liefert bei Erfolg TRUE ! * ! * @param string needle ! * @param array haystack ! * @return boolean ! / ! function inArray(needle, haystack) { ! var length = haystack.length; ! for(var i = 0; i < length; i++) { ! if(haystack _== needle) return true; ! } ! return false; ! } ! /* ! * Gibt zurück, ob die capabilities ein Steuern zulassen ! * ! * @param array capabilities ! * @return boolean ! / ! function deviceIsControllable(capabilities) { ! return (inArray('AUDIO_PLAYER', capabilities) ! || inArray('AMAZON_MUSIC', capabilities) ! || inArray('TUNE_IN', capabilities)); ! } ! /* ! * Gibt zurück, ob die capabilities eine Audiowiedergabe zulassen ! * ! * @param array capabilities ! * @return boolean ! / ! function deviceHasMusicPlayer(capabilities) { ! return (inArray('AUDIO_PLAYER', capabilities) ! || inArray('AMAZON_MUSIC', capabilities)); ! } ! /* ! * Gibt zurück, ob die capabilities TuneIn und somit Radio zulassen ! * ! * @param array capabilities ! * @return boolean ! / ! function deviceHasTuneIn(capabilities) { ! return (inArray('TUNE_IN', capabilities)); ! } ! /* ! * Button wieder auf false zurücksetzen, wenn er true war, danach callback ! * ! * @param object obj ! * @param function callback ! / ! function unsetButtonFirst(obj, callback) { ! if(getState(obj.id).val) { ! setState(obj.id,false); ! if(callback !== undefined && typeof callback === 'function') callback(obj); ! } ! } ! /* ! * Liefert str als String zurück, '' anstelle von null, false, … ! * ! * @param mixed str ! * @return string ! / ! function getStringOrEmpty(str){ ! return (String(str) !== 'undefined') ? String(str) : ''; ! } ! /* ! * Liefert das Device anhand der seriennummer ! * ! * @param string serialNumber ! * @param object ! / ! function getDeviceNameBySerialNumber(serialNumber) { ! for (device in devices) { ! if (devices[device].serialNumber == serialNumber) { ! return device; ! } ! } ! return null; ! } ! /* ! * Liefert das erste Device das einen MusicPlayer hat, ! * oder null, wenn es keines gibt ! * ! * @return object|null ! / ! function getEchoWithMusicPlayerFromDevices() { ! for (device in devices) { ! if (deviceHasMusicPlayer(devices[device].capabilities)) { ! return devices[device]; ! } ! } ! return null; ! } ! /* ! * Liefert einen bereinigten Namen um daraus einen State-Pfad zu erzeugen ! * ! * @param string name ! * @return string ! / ! function clearName(name){ ! name = umlaut(name); ! name = name.replace(/\W/g,"_"); ! return name; ! } ! /* ! * Ersetzt Umlaufe/Sonderzeichen ! * ! * @param string str ! * @return string ! / ! function umlaut(str) { ! return str ! .replace(/Â|À|Å|Ã/g, "A") ! .replace(/â|à|å|ã/g, "a") ! .replace(/Ä/g, "AE") ! .replace(/ä/g, "ae") ! .replace(/Ç/g, "C") ! .replace(/ç/g, "c") ! .replace(/É|Ê|È|Ë/g, "E") ! .replace(/é|ê|è|ë/g, "e") ! .replace(/Ó|Ô|Ò|Õ|Ø/g, "O") ! .replace(/ó|ô|ò|õ/g, "o") ! .replace(/Ö/g, "OE") ! .replace(/ö/g, "oe") ! .replace(/Š/g, "S") ! .replace(/š/g, "s") ! .replace(/ß/g, "ss") ! .replace(/Ú|Û|Ù/g, "U") ! .replace(/ú|û|ù/g, "u") ! .replace(/Ü/g, "UE") ! .replace(/ü/g, "ue") ! .replace(/Ý|Ÿ/g, "Y") ! .replace(/ý|ÿ/g, "y") ! .replace(/Ž/g, "Z") ! .replace(/ž/, "z"); ! } ! /* ! * Liefert einen String zum http-Status ! * ! * @param integer status ! * @return string ! / ! function statusCode(status) { ! if(status === 0) return "* Daten unvollständig ** (csrf fehlt/falsch? Cookie falsch?)"; ! if(status == 200) return "** OK "; ! if(status == 302) return " Found (Moved Temporarily) ** (Cookie abgelaufen?)"; ! if(status == 401) return "** Unauthorized ** (Cookie nicht richtig gesetzt?)"; ! if(status == 403) return "** Forbidden ** (Kombination Cookie, deviceType, Seriennummer richtig?)"; ! if(status == 404) return "** Not Found ** (Kommando im Kontext des Geräts sinnvoll?)"; ! if(status == 500) return "** Internal Server Error** (ggf. Kommando im falschen Kontext verwendet?)"; ! return "Fehler"; ! } ! /** ! * Liefert einen String zum deviceType ! * ! * @param integer deviceType ! * @return string ! / ! function deviceTypeStr(deviceType){ ! if(!knownDeviceType[deviceType] || knownDeviceType[deviceType] === undefined) return "Gerät unbekannt"; ! return knownDeviceType[deviceType]; ! } ! /* ! * Konvertiert eine Sekundenzahl in einen String im Format (HH:)MM:SS ! * ! * @param integer sek ! * @return string ! */ ! function sekToHMS(sek) { ! if (sek === 0) { ! return '0'; ! } ! var sec_num = parseInt(sek, 10); ! var hours = Math.floor(sec_num / 3600); ! var minutes = Math.floor((sec_num - (hours * 3600)) / 60); ! var seconds = sec_num - (hours * 3600) - (minutes * 60); ! if (minutes < 10) {minutes = "0"+minutes;} ! if (seconds < 10) {seconds = "0"+seconds;} ! if (hours === 0) { ! return minutes+':'+seconds; ! } ! if (hours < 10) {hours = "0"+hours;} ! return hours+':'+minutes+':'+seconds; ! }___________________________ _____________z.Beispiel was bedeuten die Zahlen am Ende von dem Fehler. Ist die Zeile von der Error im Script auftritt ? y controller[0]: at IncomingMessage. <anonymous>(script.js.Alexa_Device_Command:214:81) Caught 2018-06-12 20:38:20.461 error by controller[0]: at dpAbfrageAlexaAnlegen (script.js.Alexa_Device_Command:245:32) Caught 2018-06-12 20:38:20.461 error by controller[0]: at Object.parse (native) Caught 2018-06-12 20:38:20.461 error by controller[0]: SyntaxError: Unexpected end of JSON input</anonymous>_____________
  • Wiederkehrende Logik für das Schalten von Szenen

    Verschoben
    4
    0 Stimmen
    4 Beiträge
    444 Aufrufe
    T
    Besten Dank. Gute Idee Ich werde das bei Gelegenheit umsetzten
  • CCU2 - Firmwareversion auslesen

    Verschoben
    1
    0 Stimmen
    1 Beiträge
    258 Aufrufe
    Niemand hat geantwortet
  • Fritz CallMonitor Status vom Klingelknopf 2n Türstation abfragen

    Verschoben
    3
    0 Stimmen
    3 Beiträge
    571 Aufrufe
    tvtotalT
    Danke Alternativ Code funktioniert!
  • Benötige Hilfe bei der Script Erstellung

    Verschoben
    3
    0 Stimmen
    3 Beiträge
    375 Aufrufe
    2
    @paul53: @2hot4you: Wie kann ich eine Variable mit dem errechneten Wert füllen ? ` Meinst Du damit eine Skriptvariable oder einen Datenpunkt ? Mit Datenpunkt: const idSrc = "sonoff.0.nodeMCU_10.SR04_Distance"; const idDst = "Wasserstand"; // Datenpunkt erzeugen createState(idDst, 1000 * (1 - 0.96 * getState(idSrc).val), {type: 'number', unit: 'mm'}); on(idSrc, function(dp) { // Triggern bei Wertänderung setState(idDst, 1000 * (1 - 0.96 * dp.state.val), true); }); https://github.com/ioBroker/ioBroker.javascript/blob/master/doc/en/javascript.md ` Danke, klappt super !!! :D :D jetzt muss es nur noch Regnen ! [image: 4872_regen.png]
  • Mehrere on()-Abfragen, mit vorheriger State-Abfrage

    Verschoben
    3
    0 Stimmen
    3 Beiträge
    551 Aufrufe
    PaSiP
    Herzlichen Dank, auf die Idee bin ich keinesfalls gekommen. Werde ich gleich mal ausprobieren :) Gesendet von meinem SM-G955F mit Tapatalk
  • Wert in Objekt über Blockly schreiben - NaN

    Verschoben
    7
    0 Stimmen
    7 Beiträge
    2k Aufrufe
    R
    Danke! Das war genau mein Verständnis Problem - dachte wenn ich das raus nehme wird es nicht berücksichtigt. So blind muss man mal sein das man den Mistkübel nicht sieht 8-) lg, Thorsten
  • Tr 064 Adapter belegte Leitung abfragen

    Verschoben
    3
    1
    0 Stimmen
    3 Beiträge
    321 Aufrufe
    M
    Just im Moment habe ich die Lösung gefunden. Ich frage nicht das TR-064 Objekt ab, das bietet mir dafür keinen Datenpunkt, sondern das Fritzbox.0 Objekt. Damit funktioniert es einwandfrei. Die Lösung ist jedoch nur für Singlehaushalte geeignet. Wenn jemand den ton z.B. mit der Fernbedienung wieder einschaltet wird der Ton bei beenden des Telefonates wieder abgeschaltet. 7022_ruhe_telefon.jpeg
  • Adapter temporär deaktivieren

    Verschoben
    1
    1
    0 Stimmen
    1 Beiträge
    219 Aufrufe
    Niemand hat geantwortet
  • [gelöst] Spritpreis Benachrichtigung

    Verschoben
    24
    1
    0 Stimmen
    24 Beiträge
    3k Aufrufe
    S
    hier noch mal meine komplette lösung: ich habe doch noch eine Verzögerung eingebaut, weil der Name der Tankstelle das selbe Problem ergeben hat (wert ist leer beim aktualisieren für etwa 1,5 sek) wie vorher schon mit dem wert von dem preis (war "0" während dem aktualisieren). der Name der Tankstelle wird nicht auf null gesetzt, aber er ist einfach leer, dauert ca.1,5 Sekunden bis er wieder drin steht. in meinem Fall nimmt er SONST den Standard betreff. daher soll er einfach 3 Sekunden später pushen … spielt ja keine große rolle ... So klappt es ! [image: 6131_unbenannt6.png]
  • Wie socket.io-client in js-script verwenden

    Verschoben
    2
    0 Stimmen
    2 Beiträge
    541 Aufrufe
    Jey CeeJ
    Das Modul aus dem socketio Adapter ist nicht global verfügbar. Du musst das Modul in der JS Adapter Config eintragen, dann wird es installiert und steht dir zur Verfügung.

757

Online

32.4k

Benutzer

81.4k

Themen

1.3m

Beiträge