NEWS
Volumio adapter?
-
@saeft_2003 ich ebbeso. war nur spielerei. mit raspis hats eh mehr sinn. vor allem wenn mehrere vorhanden sind und man multiroom betreiben will.
-
Hi,
ich habe mir, basierend auf der Volumio API, ein Skript geschrieben, welches die folgenden Objekte zur Steuerung und Anzeige von Informationen erzeugt und beschreibt. Da Skript ist natürlich fähig, mit mehreren Volumios zu arbeiten. Bei mir sind aktuell 4 Volumio RPi's im Einsatz.<yourFolder>.Player.Volumio_Player_0: folder - Volumio_Player_0 <yourFolder>.Player.Volumio_Player_0.Infos: folder - Infos <yourFolder>.Player.Volumio_Player_0.Infos.Audio: folder - Audio <yourFolder>.Player.Volumio_Player_0.Infos.Audio.CoverArt: state - CoverArt from Moodeaudio and mpd adapter <yourFolder>.Player.Volumio_Player_0.Infos.Audio.HiRes_Audio: state - HiRes Anzeige <yourFolder>.Player.Volumio_Player_0.Infos.Audio.Source_Channels: state - Audiokanaele der Quelldatei <yourFolder>.Player.Volumio_Player_0.Infos.Audio.Source_SampleRate: state - Abtastfrequenz der Quelldatei <yourFolder>.Player.Volumio_Player_0.Infos.Audio.Source_SampleRateDisplay: state - Abtastfrequenz der Quelldatei <yourFolder>.Player.Volumio_Player_0.Infos.Audio.Source_bitdeepth: state - Bittiefe der Quelldatei <yourFolder>.Player.Volumio_Player_0.PlayPause: state - PlayPause Toggle <yourFolder>.Player.Volumio_Player_0.control: folder - control <yourFolder>.Player.Volumio_Player_0.control.PlayPause_controlFolder: state - PlayPause_controlFolder <yourFolder>.Player.Volumio_Player_0.control.mute: state - mute <yourFolder>.Player.Volumio_Player_0.control.mute_toggle: state - mute_toggle <yourFolder>.Player.Volumio_Player_0.control.next: state - next <yourFolder>.Player.Volumio_Player_0.control.pause: state - pause <yourFolder>.Player.Volumio_Player_0.control.play: state - play <yourFolder>.Player.Volumio_Player_0.control.previous: state - previous <yourFolder>.Player.Volumio_Player_0.control.removeAllReceiver: state - Remove all Receiver Pis from receiving <yourFolder>.Player.Volumio_Player_0.control.removeAsReceiver: state - Remove pi from multiroom if pi is a Receiver <yourFolder>.Player.Volumio_Player_0.control.stop: state - stop <yourFolder>.Player.Volumio_Player_0.control.unmute: state - unmute <yourFolder>.Player.Volumio_Player_0.control.volume_down: state - volume_down <yourFolder>.Player.Volumio_Player_0.control.volume_up: state - volume_up <yourFolder>.Player.Volumio_Player_0.playbackInfo: folder - playbackInfo <yourFolder>.Player.Volumio_Player_0.playbackInfo.album: state - Album of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.albumart: state - Cover url of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.artist: state - Artist of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.bitdepth: state - bitdepth of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.bitdepthRaw: state - raw bitdepth of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.bitrate: state - bitrate of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.bitrateRaw: state - raw bitrate of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.bitrateRaw2: state - raw bitrate of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.channels: state - channels of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.consume: state - consume <yourFolder>.Player.Volumio_Player_0.playbackInfo.dbVolume: state - volume in dB <yourFolder>.Player.Volumio_Player_0.playbackInfo.disableVolumeControl: state - Shuffle playmode activated <yourFolder>.Player.Volumio_Player_0.playbackInfo.duration: state - Duration of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.duration_mmss: state - Duration of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.duration_ms: state - Duration of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.multiroom: state - indicates player in multiroom mode <yourFolder>.Player.Volumio_Player_0.playbackInfo.multiroomPlaying: state - indicates player in multiroom mode <yourFolder>.Player.Volumio_Player_0.playbackInfo.multiroomReceiver: state - indicates player in Receiver multiroom mode <yourFolder>.Player.Volumio_Player_0.playbackInfo.multiroomReceivingFromID: state - indicates multiroom mode Mother <yourFolder>.Player.Volumio_Player_0.playbackInfo.multiroomReceivingFromName: state - indicates multiroom mode Mother <yourFolder>.Player.Volumio_Player_0.playbackInfo.multiroomSender: state - indicates player in Sender multiroom mode <yourFolder>.Player.Volumio_Player_0.playbackInfo.mute: state - muted status <yourFolder>.Player.Volumio_Player_0.playbackInfo.position: state - Position in playlist of current track-start at 0 <yourFolder>.Player.Volumio_Player_0.playbackInfo.positionCorrected: state - Position in playlist of current track-start at 1 <yourFolder>.Player.Volumio_Player_0.playbackInfo.random: state - Repeat playlist activated <yourFolder>.Player.Volumio_Player_0.playbackInfo.repeat: state - Repeat playlist activated <yourFolder>.Player.Volumio_Player_0.playbackInfo.repeatSingle: state - Repeat current track activated <yourFolder>.Player.Volumio_Player_0.playbackInfo.samplerate: state - samplerate of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.samplerateRaw: state - raw samplerate of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.samplerateRaw2: state - raw samplerate of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.seek: state - Seek position of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.seek_mmss: state - Seek position of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.seek_percent: state - Seek position of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.seek_s: state - Seek position of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.service: state - service where playback is from <yourFolder>.Player.Volumio_Player_0.playbackInfo.status: state - Playback status <yourFolder>.Player.Volumio_Player_0.playbackInfo.statusIncomingCall: state - Playback status Call is incoming <yourFolder>.Player.Volumio_Player_0.playbackInfo.statusLastValue: state - Playback status Last Value <yourFolder>.Player.Volumio_Player_0.playbackInfo.stream: state - stream <yourFolder>.Player.Volumio_Player_0.playbackInfo.title: state - Title of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.titleRaw: state - Title of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.trackType: state - Type of current track (flac/mp3/acc/..) <yourFolder>.Player.Volumio_Player_0.playbackInfo.updatedb: state - updatedb <yourFolder>.Player.Volumio_Player_0.playbackInfo.uri: state - rl of current track <yourFolder>.Player.Volumio_Player_0.playbackInfo.volatile: state - volatile <yourFolder>.Player.Volumio_Player_0.playbackInfo.volume: state - volume in percent
Besteht hier Interesse an diesem Skript?
-
@muellerra ja, hätte interesse
-
@da_woody sagte in Volumio adapter?:
nachdem ich vor einiger zeit im stammlokal raspis mit volumio (https://volumio.com/en/get-started/) installiert habe, mal umgeschaut und auf https://github.com/a-i-ks/ioBroker.volumio gekommen. leider seit 2 jahren nix neues.
ich meine, es gibt eine gute API dazu, kann aber nicht proggen. https://volumio.github.io/docs/API/API_Overview.html
hat da wer lust und laune?Es gibt ja kein einziges issue dies bezüglich beim Adapter wie soll der Entwickler wissen was spielt ?
-
@da_Woody
Und an alle anderen die ein Problem zu haben scheinen.Bitte erstellt ein ISSUE im Adapterrepository wenn etwas nicht funkioniert und gebt den Link dazu auch hier an.
Neben der Problembeschreibung incl. log bitte unbedingt angeben:
- Adapterversion
- js-controller version
- node-js
- o/s
DANKE
UND NOCH WAS
Wenn jemand den volumio Adapetr erfolgreich am Laufen hat - BITTE AUCH HIER MELDEN.
-
@dutchman sorry, wie gesagt, im Stammlokal.
Zu Hause nur einen zum rumspielen.
Daher eher keine Priorität.
War nur so eine Idea... -
@da_woody said in Volumio adapter?:
@dutchman sorry, wie gesagt, im Stammlokal.
Zu Hause nur einen zum rumspielen.
Daher eher keine Priorität.
War nur so eine Idea...Was willst du uns damit sagen?
- Funktioniert der Adapter nun?
- Funktioniert der Adapter nicht? Dann bitte Issue?
- Oder weißt du es nicht, da ihn (derzeit) nicht (mehr) benutzt?
Wär schön eine Rückmeldung zu bekommen ob der Adapter nun in Ordnung zu sein scheint oder nicht ...
-
@mcm57 sagte in Volumio adapter?:
Oder weißt du es nicht, da ihn (derzeit) nicht (mehr) benutzt?
werd mich die nächsten tage damit beschäftigen...
-
@mcm57 so, gestern nachmittag den adapter nochmals installiert. mächtig probleme...
am abend war dann österreich : deutschland wichtiger...
issue hab ich hoffentlich ausreichend erstellt.
https://github.com/a-i-ks/ioBroker.volumio/issues/12
getestet mit nem frisch installiertem volumio auf nem raspi 3b.
hier noch ein log im debug mode...volumio.0 2023-11-22 09:22:26.508 info terminating volumio.0 2023-11-22 09:22:26.048 info State value to set for "volumio.0.playbackInfo.position" has to be type "string" but received type "number" volumio.0 2023-11-22 09:22:26.007 warn Terminated (UNCAUGHT_EXCEPTION): Without reason volumio.0 2023-11-22 09:22:26.006 info terminating volumio.0 2023-11-22 09:22:25.999 error undefined is not a valid state value volumio.0 2023-11-22 09:22:25.999 error Error: undefined is not a valid state value at Object.maybeCallbackWithError (/opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/maybeCallback.js:35:17) at Volumio._setState (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/build/lib/adapter/adapter.js:5448:49) at Volumio.setState (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/build/lib/adapter/adapter.js:5409:21) at /opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/tools.js:2020:16 at new Promise (<anonymous>) at Volumio.setStateAsync (/opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/tools.js:2019:16) at Volumio.propagatePlayserStateIntoStates (/opt/iobroker/node_modules/iobroker.volumio/build/main.js:267:14) at /opt/iobroker/node_modules/iobroker.volumio/build/main.js:254:18 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) volumio.0 2023-11-22 09:22:25.999 error unhandled promise rejection: undefined is not a valid state value volumio.0 2023-11-22 09:22:25.999 error Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). volumio.0 2023-11-22 09:22:25.998 error undefined is not a valid state value volumio.0 2023-11-22 09:22:25.998 error Error: undefined is not a valid state value at Object.maybeCallbackWithError (/opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/maybeCallback.js:35:17) at Volumio._setState (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/build/lib/adapter/adapter.js:5448:49) at Volumio.setState (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/build/lib/adapter/adapter.js:5409:21) at /opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/tools.js:2020:16 at new Promise (<anonymous>) at Volumio.setStateAsync (/opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/tools.js:2019:16) at Volumio.propagatePlayserStateIntoStates (/opt/iobroker/node_modules/iobroker.volumio/build/main.js:262:14) at /opt/iobroker/node_modules/iobroker.volumio/build/main.js:254:18 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) volumio.0 2023-11-22 09:22:25.998 error unhandled promise rejection: undefined is not a valid state value volumio.0 2023-11-22 09:22:25.998 error Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). volumio.0 2023-11-22 09:22:25.997 error undefined is not a valid state value volumio.0 2023-11-22 09:22:25.996 error Error: undefined is not a valid state value at Object.maybeCallbackWithError (/opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/maybeCallback.js:35:17) at Volumio._setState (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/build/lib/adapter/adapter.js:5448:49) at Volumio.setState (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/build/lib/adapter/adapter.js:5409:21) at /opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/tools.js:2020:16 at new Promise (<anonymous>) at Volumio.setStateAsync (/opt/iobroker/node_modules/@iobroker/js-controller-common/build/lib/common/tools.js:2019:16) at Volumio.propagatePlayserStateIntoStates (/opt/iobroker/node_modules/iobroker.volumio/build/main.js:260:14) at /opt/iobroker/node_modules/iobroker.volumio/build/main.js:254:18 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) volumio.0 2023-11-22 09:22:25.995 error unhandled promise rejection: undefined is not a valid state value volumio.0 2023-11-22 09:22:25.994 error Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). volumio.0 2023-11-22 09:22:25.964 debug Checking subscrition urls ... volumio.0 2023-11-22 09:22:25.963 debug Server is listening on 192.168.0.250:3042 volumio.0 2023-11-22 09:22:25.960 debug Subscription mode is activated volumio.0 2023-11-22 09:22:25.955 debug Ping response volumio.0 2023-11-22 09:22:25.907 debug Pinging volumio ... volumio.0 2023-11-22 09:22:25.874 info starting. Version 0.1.2 in /opt/iobroker/node_modules/iobroker.volumio, node: v18.18.2, js-controller: 5.0.16
-
Hi, @farmer-cb , entschuldige die späte Rückmeldung, da ist irgendwas mit meinen Benachrichtigungseinstellunge schief gelaufen...
Anbei einmal die Skripte. Gleich vorneweg: Sollten die IP-Adresse ungleich
192.168.178.XXX
sein, oder der Ordner ein anderer als bei mir (javascript.0.Allgemeine_Variablen.Player.Volumio_Player_*
) sein -> bitte per suchen und ersetzen anpassen.
Der ping Adapter muss ebenfalls installiert sein -> in Zeile 601 (if(getState('ping.1.rrBroker.' + Volumios[ID_Volumio]).val){
) bitteping.1.rrBroker.
entsprechend der installierten ping Instanz und dem entsprechenden iobroker-Hostnamen ersetzen. Das Gerät im ping Adapter muss genauso benannt sein, wie es in Zeile 8:var Volumios = ["rStream","workStream","kitchenStream","flurStream"]
definiert ist. (Bei mir
ping.1.rrBroker.workStream
). Wer im ping Adapter die erweiterten Infos verwendet muss ein .alive anhängen:if(getState('ping.<instance>.<iobrokerHostName>.' + Volumios[ID_Volumio] + '.alive').val){
Hier ist das Hauptskript:
/// Read out volumio via rest api var request = require('request'); var querystring = require('querystring'); var pollingInterval = 500//in ms var Folder = 'javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' // var Volumios = ["rStream","workStream","kitchenStream","flurStream"] //muss in beiden Skripten identisch sein var Volumios_IPs = ["82","58","48","72"] //192.168.178 wird dann im Skript hart gesetzt -> ggf. abändern! Reihenfolge der IPs muss mit den drüber definierten Namen übereinstimmen! var getStates_States_with_RawValues = ['samplerate','bitdepth','title','bitrate'] var getStates_States_wo_RawValues = ['status','artist','album','albumart','uri','trackType','duration','seek','service','channels','consume','volume','dbVolume','mute','disableVolumeControl','stream','volatile', 'updatedb','trackType','random','position','repeatSingle','repeat'] var getStates_States = getStates_States_wo_RawValues.concat(getStates_States_with_RawValues) //States erstellen // ToDo -> states nur erstellen wenn sie nicht exisitieren for (ID_Volumio in Volumios){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroom',false ,{"role": "indicator", "name": "indicates player in multiroom mode", "type": "boolean", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomPlaying',false ,{"role": "indicator", "name": "indicates player in multiroom mode", "type": "boolean", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomSender', false,{"role": "indicator", "name": "indicates player in Sender multiroom mode", "type": "boolean", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceiver', false,{"role": "indicator", "name": "indicates playerstate in Receiver multiroom mode", "type": "boolean", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceivingFromName', "",{"role": "text", "name": "indicates multiroom mode Mother", "type": "string", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceivingFromID', 99,{"role": "value", "name": "indicates multiroom mode Mother", "type": "number", "read": true, "write": true }) for (Stati in getStates_States){ var field = getStates_States[Stati] if(field == "updatedb"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "indicator", "name": "updatedb", "type": "boolean", "read": true, "write": true }) } if(field == "trackType"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "text", "name": "Type of current track (flac/mp3/acc/..)", "type": "string", "read": true, "write": true }) } if(field == "random"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "indicator", "name": "Repeat playlist activated", "type": "boolean", "read": true, "write": true }) } if(field == "repeatSingle"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.state", "name": "Repeat current track activated", "type": "boolean", "read": true, "write": true }) } if(field == "position"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.track", "name": "Position in playlist of current track-start at 0", "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Corrected', {"role": "media.track", "name": "Position in playlist of current track-start at 1", "type": "number", "read": true, "write": true }) } if(field == "repeat"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.mode.repeat", "name": "Repeat playlist activated", "type": "boolean", "read": true, "write": true }) } if(field == "status"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.state", "name": "Playback status", "type": "string", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'LastValue', {"role": "media.state", "name": "Playback status Last Value", "type": "string", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'IncomingCall', {"role": "media.state", "name": "Playback status Call is incoming", "type": "string", "read": true, "write": true }) } if(field == "title"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.title", "name": "Title of current track", "type": "string", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Raw', {"role": "media.title", "name": "Title of current track", "type": "string", "read": true, "write": true }) } if(field == "artist"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.artist", "name": "Artist of current track", "type": "string", "read": true, "write": true }) } if(field == "album"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.album", "name": "Album of current track", "type": "string", "read": true, "write": true }) } if(field == "albumart"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.cover", "name": "Cover url of current track", "type": "string", "read": true, "write": true }) } if(field == "uri"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.url", "name": "rl of current track", "type": "string", "read": true, "write": true }) } if(field == "trackType"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "text", "name": "Type of current track (flac/mp3/acc/..)", "type": "string", "read": true, "write": true }) } if(field == "seek"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.seek","unit":"ms", "name": "Seek position of current track", "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_percent', {"role": "media.seek","unit":"%", "name": "Seek position of current track", "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_s', {"role": "media.seek","unit":"s", "name": "Seek position of current track", "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_mmss', {"role": "text", "name": "Seek position of current track", "type": "string", "read": true, "write": true }) } if(field == "duration"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.duration","unit":"s", "name": "Duration of current track", "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_ms', {"role": "media.duration","unit":"ms", "name": "Duration of current track", "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_mmss', {"role": "text", "name": "Duration of current track", "type": "string", "read": true, "write": true }) } if(field == "samplerate"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "string", "name": "samplerate of current track", "type": "string", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Raw', {"role": "media.samplerate", "name": "raw samplerate of current track ", "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Raw2', {"role": "media.samplerate", "name": "raw samplerate of current track ", "type": "string", "read": true, "write": true }) } if(field == "bitrate"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "string", "name": "bitrate of current track", "type": "string", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Raw', {"role": "media.bitrate", "name": "raw bitrate of current track ","unit":'kbps', "type": "number", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Raw2', {"role": "media.bitrate", "name": "raw bitrate of current track ", "type": "string", "read": true, "write": true }) } if(field == "bitdepth"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "text", "name": "bitdepth of current track", "type": "string", "read": true, "write": true }) createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Raw', {"role": "media.bitdepth", "name": "raw bitdepth of current track", "unit": "bit", "type": "number", "read": true, "write": true }) } if(field == "channels"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "value", "name": "channels of current track", "type": "number", "read": true, "write": true }) } if(field == "consume"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "indicator", "name": "consume", "type": "boolean", "read": true, "write": true }) } if(field == "volume"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "level.volume", "name": "volume in percent", "unit": "%","type": "number", "read": true, "write": true }) } if(field == "dbVolume"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "level.volume", "name": "volume in dB", "unit": "dB","type": "number", "read": true, "write": true }) } if(field == "mute"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "media.mute", "name": "muted status", "type": "boolean", "read": true, "write": true }) } if(field == "disableVolumeControl"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "indicator", "name": "Shuffle playmode activated", "type": "boolean", "read": true, "write": true }) } if(field == "stream"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "text", "name": "stream", "type": "string", "read": true, "write": true }) } if(field == "volatile"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "indicator", "name": "volatile", "type": "boolean", "read": true, "write": true }) } if(field == "service"){ createState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field, {"role": "text", "name": "service where playback is from", "type": "string", "read": true, "write": true }) } } } //------------ get Informations per intervall ------------------------- var timer var intervall clearTimeout(timer) clearInterval(intervall) timer = setTimeout(function () { timer = null; intervall= null; clearTimeout(timer); clearInterval(intervall); intervall = setInterval(getVolumioStates, pollingInterval, Volumios_IPs ) }, 1000 * 3); //10 sekunden dieder motion sensor noch braucht zum zurücksetzen sind aufzuaddieren //------------ get Informations per intervall ------------------------- //------------------ create listener for raw values ------------------- var getStates_States_with_RawValuesWithAddListeners = getStates_States_with_RawValues.concat(['status','channels']) for (ID_Volumio in Volumios_IPs){ for (Stati in getStates_States_with_RawValuesWithAddListeners){ on({id: Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + getStates_States_with_RawValuesWithAddListeners[Stati], change: 'any'}, function (obj) { var value = obj.state.val; var oldValue = obj.oldState.val var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) //untescheidung nach kHz mHz! if (StateName == 'title'){ splitted = value.split(' ') firstIsNumber = typeof(parseFloat(splitted[0])) if(typeof(parseFloat(splitted[0])) == "number"){ firstIsNumber = true }else{firstIsNumber=false} if(splitted[1] == "-"){ secondStrich = true }else{secondStrich=false} if(firstIsNumber === true && secondStrich === true){ delete splitted[1] delete splitted[0] result = splitted.join(' ') }else{result = value} setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw', result) }else if (StateName == 'status'){ var StatusOldValue = getState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName).val setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'LastValue',oldValue) }else if (StateName == 'channels'){ setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.Infos.Audio.Source_Channels', parseFloat(value)) }else if (StateName == 'bitrate'){ log(ID_Volumio_Verursacher + ": Receiving: " + getState(Folder+ID_Volumio_Verursacher+'.playbackInfo.multiroomReceiver').val) if(String(value).toLowerCase().includes('kbps')){ result = parseFloat(value) setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw2', result + ' kbps') }else{result = 0 setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw2', 'notAvailable') } }else if (StateName == 'bitdepth'){ var BitDepthTemp = parseFloat(value) result = BitDepthTemp var SampleRateTemp = getState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRate').val var ServiceTemp = getState(Folder + ID_Volumio_Verursacher + '.playbackInfo.service').val if((BitDepthTemp > 16 || SampleRateTemp > 48000) && ServiceTemp != 'multiroom' ){ setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.HiRes_Audio',true) }else{ setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.HiRes_Audio',false) } setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_bitdeepth', parseFloat(value)) if(value == 'notAvailable'){ setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_bitdeepthDisplay', 'notAvailable') }else{ setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_bitdeepthDisplay', String(value)) } }else if (StateName == 'samplerate'){ var SampleRateTemp = parseFloat(value) var BitDepthTemp = getState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_bitdeepth').val var ServiceTemp = getState(Folder + ID_Volumio_Verursacher + '.playbackInfo.service').val log("BitDepthTemp 2:" + BitDepthTemp) if((BitDepthTemp > 16 || SampleRateTemp > 48000) && ServiceTemp != 'multiroom'){ setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.HiRes_Audio',true) }else{setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.HiRes_Audio',false)} if(String(value).toLowerCase().includes('khz')){ result = parseFloat(value)*1000 setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw2', result/1000 + ' kHz') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRateDisplay', result/1000 + ' kHz') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRate', result) } else if(String(value).toLowerCase().includes('mhz')){ result = parseFloat(value)*1000000 setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw2', result/1000000 + ' MHz') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRateDisplay', result/1000000 + ' MHz') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRate', result) }else if(String(value).toLowerCase().includes('kbps')){ result = parseFloat(value) setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw2', result + ' kbps') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRateDisplay', result + ' kbps') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRate', 0) }else if(value == null||value == 'null' ||value == 'undefined' || value == undefined||value == 'notAvailable'){ result = 0 setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw2', 'notAvailable') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRateDisplay', 'notAvailable') setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRate', 0) }else{result = parseFloat(value)} }else{ result = parseFloat(value) } if (StateName != 'service' && StateName != 'status' && StateName != 'channels'){ setState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + StateName + 'Raw', result) } }); } } //------------------ create listener for raw values ------------------- // ------------------ states for control ------------------------ var Buttons_Control = ['next','previous','play','pause','stop','mute','unmute','mute_toggle','PlayPause','PlayPause_controlFolder','volume_up','volume_down','removeAsReceiver','removeAllReceiver'] var VolumioAPIString1 = "http://" var VolumioAPIStringCommand = "/api/v1/commands/?cmd=" for (ID_Volumio in Volumios_IPs){ var FolderPlayer = Folder + String(parseInt(ID_Volumio)) var FolderControl = FolderPlayer + '.control' for (iter in Buttons_Control){ // console.log(iter) if (Buttons_Control[iter] == "VolumeControl_ID"){ createState(FolderControl+'.'+Buttons_Control[iter],false, {role:"value", type: "string",name: Buttons_Control[iter] }) setState(FolderControl+'.'+Buttons_Control[iter],false) }else if (Buttons_Control[iter] == "Volume"){ createState(FolderControl+'.'+Buttons_Control[iter],false, {role:"value", type: "number",name: Buttons_Control[iter] }) setState(FolderControl+'.'+Buttons_Control[iter],false) }else if (Buttons_Control[iter] == "removeAsReceiver"){ createState(FolderControl+'.'+Buttons_Control[iter],false, {role:"button", type: "boolean",name: 'Remove pi from multiroom if pi is a Receiver' }) setState(FolderControl+'.'+Buttons_Control[iter],false) }else if (Buttons_Control[iter] == "removeAllReceiver"){ createState(FolderControl+'.'+Buttons_Control[iter],false, {role:"button", type: "boolean",name: 'Remove all Receiver Pis from receiving' }) setState(FolderControl+'.'+Buttons_Control[iter],false) }else if (Buttons_Control[iter] == "PlayPause"){ createState(FolderPlayer+'.'+Buttons_Control[iter],false, {role:"button", type: "boolean",name: Buttons_Control[iter] + ' Toggle' }) setState(FolderPlayer+'.'+Buttons_Control[iter],false) } else{ createState(FolderControl+'.'+Buttons_Control[iter],false, {role:"button", type: "boolean",name: Buttons_Control[iter] }) setState(FolderControl+'.'+Buttons_Control[iter],false) } } on({id: FolderControl+'.'+Buttons_Control[0], change: 'ne'}, function (obj) { // next var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var ID_Multiroom_Temp = parseInt(getState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + 'multiroomReceivingFromID').val) if(ID_Multiroom_Temp != 99 && ID_Multiroom_Temp <= parseInt(Volumios.length)){ // sicherehits auf länge ID_Volumio_Verursacher = ID_Multiroom_Temp } if(value === true){ //do something var command = "next" var URL = VolumioAPIString1 + '192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[1], change: 'ne'}, function (obj) { // previous var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var ID_Multiroom_Temp = parseInt(getState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + 'multiroomReceivingFromID').val) if(ID_Multiroom_Temp != 99 && ID_Multiroom_Temp <= parseInt(Volumios.length)){ ID_Volumio_Verursacher = ID_Multiroom_Temp } if(value === true){ //do something var command = "prev" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[2], change: 'ne'}, function (obj) { // play var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var ID_Multiroom_Temp = parseInt(getState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + 'multiroomReceivingFromID').val) if(ID_Multiroom_Temp != 99 && ID_Multiroom_Temp <= parseInt(Volumios.length)){ ID_Volumio_Verursacher = ID_Multiroom_Temp } if(value === true){ //do something var command = "play" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[3], change: 'ne'}, function (obj) { // pause var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var ID_Multiroom_Temp = parseInt(getState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + 'multiroomReceivingFromID').val) if(ID_Multiroom_Temp != 99 && ID_Multiroom_Temp <= parseInt(Volumios.length)){ ID_Volumio_Verursacher = ID_Multiroom_Temp } if(value === true){ //do something var command = "pause" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[4], change: 'ne'}, function (obj) { // stop var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) if(value === true){ //do something var command = "stop" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[5], change: 'ne'}, function (obj) { // mute var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) if(value === true){ //do something var command = "volume&volume=mute" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[6], change: 'ne'}, function (obj) { // unmute var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) if(value === true){ //do something var command = "volume&volume=unmute" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[7], change: 'ne'}, function (obj) { // mute_toggle var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) if(value === true){ //do something var MuteStateTemp = getState(Folder + String(ID_Volumio_Verursacher) + '.playbackInfo.mute').val if (MuteStateTemp === false || MuteStateTemp == "false"){ //muten var command = "volume&volume=mute" }else if (MuteStateTemp === true || MuteStateTemp == "true"){ //unmuten var command = "volume&volume=unmute" } var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderPlayer+'.'+Buttons_Control[8], change: 'any'}, function (obj) { // PlayPause //ACHTUNG HIER ANDERER ORDNER IM LISTENER var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio_noSubfolder(obj.id,Volumios) // ACHTUNG HIER ANDERE FUNKTION, DA ICH IN ANDEREM ORDNER UNTERWEGS BIN var ID_Multiroom_Temp = parseInt(getState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + 'multiroomReceivingFromID').val) if(ID_Multiroom_Temp != 99 && ID_Multiroom_Temp <= parseInt(Volumios.length)){ // sicherehits auf länge ID_Volumio_Verursacher = ID_Multiroom_Temp } if(value === true){ //do something var command = "toggle" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command log(URL) httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[9], change: 'ne'}, function (obj) { // PlayPause_controlFolder var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var ID_Multiroom_Temp = parseInt(getState(Folder + String(parseInt(ID_Volumio_Verursacher)) + '.playbackInfo.' + 'multiroomReceivingFromID').val) if(ID_Multiroom_Temp != 99 && ID_Multiroom_Temp <= parseInt(Volumios.length)){ // sicherehits auf länge ID_Volumio_Verursacher = ID_Multiroom_Temp } if(value === true){ //do something setState(Folder + String(ID_Volumio_Verursacher) + '.PlayPause',true) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[10], change: 'ne'}, function (obj) { // volume_up var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) if(value === true){ //do something var command = "volume&volume=plus" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command log(URL) httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[11], change: 'ne'}, function (obj) { // volume_down var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) if(value === true){ //do something var command = "volume&volume=minus" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command log(URL) httpRequest_wo_return(URL) setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[12], change: 'ne'}, function (obj) { // removeAsReceiver var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var IsPiReceiving = getState(Folder + ID_Volumio_Verursacher + '.playbackInfo.multiroomReceiver').val if(value === true){ //do something if(IsPiReceiving){ var command = "stop" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command log(URL) httpRequest_wo_return(URL) } setState(Verursacher,false) } }); on({id: FolderControl+'.'+Buttons_Control[13], change: 'ne'}, function (obj) { // removeAllReceiver var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var ReceivingVolumios = getVolumiosReceiving([],true) if(value === true){ //do something for(PiToKill in ReceivingVolumios){ var command = "stop" var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ReceivingVolumios[PiToKill]] + VolumioAPIStringCommand + command log(URL) httpRequest_wo_return(URL) } setState(Verursacher,false) } }); on({id: Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + getStates_States[11] , change: 'ne'}, function (obj) { // volume (in folder playbackinfo) var value = obj.state.val; var oldValue = obj.oldState.val; if(value != oldValue){ var NewVolume = value var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var command = "volume&volume=" + parseInt(NewVolume) var URL = VolumioAPIString1 +'192.168.178.' + Volumios_IPs[ID_Volumio_Verursacher] + VolumioAPIStringCommand + command log(URL) httpRequest_wo_return(URL) } }); } // ------------------ states for control ------------------------ //set Resetz hiRes in multiroom verbund for (ID_Volumio in Volumios_IPs){ on({id: Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceiver', change: 'any'}, function (obj) { var value = obj.state.val; var oldValue = obj.oldState.val var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumio(obj.id,Volumios) var IsChildTemp = value var ServiceTemp = getState(Folder + ID_Volumio_Verursacher + '.playbackInfo.service').val var BitDepthTemp = getState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_bitdeepth').val var SampleRateTemp = getState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.Source_SampleRate').val log("BitDepthTemp 3:" + BitDepthTemp) log("IsChildTemp 3:" + IsChildTemp) //if((BitDepthTemp > 16 || SampleRateTemp > 44100) && IsChildTemp === false && ServiceTemp != 'multiroom'){//&& getState(Folder+ID_Volumio_Verursacher+'.playbackInfo.multiroomReceiver').val === false){ if((BitDepthTemp > 16 || SampleRateTemp > 48000) && IsChildTemp === false && ServiceTemp != 'multiroom'){//&& getState(Folder+ID_Volumio_Verursacher+'.playbackInfo.multiroomReceiver').val === false){ setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.HiRes_Audio',true) }else{ setState(Folder + ID_Volumio_Verursacher + '.Infos.Audio.HiRes_Audio',false) } }); } function extract(JSONvariable,fieldname) { return getAttr((function () { try {return JSON.parse(JSONvariable);} catch(e) {return {};}})(), fieldname) } function restapiRequest(ip,command,ID_Volumio) { //sendet ssh befehl an moodeaudio muss ich eigentlich auf zertifikat umstellen var url = 'http://' + ip + '/api/v1/' + command if(getState('ping.1.rrBroker.' + Volumios[ID_Volumio]).val){ try { require("request")(url, async function (error, response, result) { if(error != null){ if(String(error).includes('read ECONNRESET') || String(error).includes('connect EHOSTUNREACH 192.168.178.') || String(error).includes('connect ECONNREFUSED 192.168.178.')){ log("ERROR Volumio: " + error) return; } } // log(getStates_States) // log(ID_Volumio + 'is receiver ' + getState(Folder + ID_Volumio + '.playbackInfo.multiroomReceiver').val) if(command == "getState"){ for (Stati in getStates_States){ var field = getStates_States[Stati] // log(field) var value = extract(result,field) if (field == 'channels'){ } if (field == 'bitrate'){ // log("Bitrate: " + value) } if (field == 'position'){ setState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + 'Corrected', parseInt(value)+1) } if (field == 'seek'){ var TrackDurationTemp = parseFloat(getState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'duration').val ) var elapsed_sec = parseFloat(value)/1000 var elapsedPercent = Math.round(100*(elapsed_sec/TrackDurationTemp)* 100) * 0.01 var elapsedMM = parseInt(elapsed_sec/60) var elapsedSS = parseInt(elapsed_sec) - 60*elapsedMM var elapsedMM_string = String(elapsedMM) var elapsedSS_string = String(elapsedSS) if(elapsedMM_string.length == 1){elapsedMM_string = '0'+elapsedMM_string} if(elapsedSS_string.length == 1){elapsedSS_string = '0'+elapsedSS_string} var elapsedMMSS = elapsedMM_string + ':' + elapsedSS_string setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_s', elapsed_sec) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_percent', elapsedPercent) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_mmss', elapsedMMSS) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_percent',elapsedPercent) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_mmss',elapsedMMSS) } if (field == 'duration'){ var duration_sec = parseFloat(value) var duration_ms = duration_sec*1000 var durationMM = parseInt(duration_sec/60) var durationSS = parseInt(duration_sec) - 60*durationMM var durationMM_string = String(durationMM) var durationSS_string = String(durationSS) if(durationMM_string.length == 1){durationMM_string = '0'+durationMM_string} if(durationSS_string.length == 1){durationSS_string = '0'+durationSS_string} var durationMMSS = durationMM_string + ':' + durationSS_string setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_mmss', durationMMSS) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_ms',duration_ms) //nur setzen wenn es eine änderung gab setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field + '_mmss',durationMMSS) } if (field == 'albumart'){ try{ if(value.includes('http') === true){ var CoverURL = value }else{ var CoverURL = 'http://' + ip + value } setState(Folder + String(ID_Volumio) + '.Infos.Audio.CoverArt',CoverURL) }catch(e){} } if (field == 'service'){ //Service muss immer gesetzt werden! umd multiroom status zu erhalten // ------------------ Multiroom Handling v2 --------------------------------------- //erst mutter dann kinder herausfinden, kann im zweifel 2 sekunden dauern //funktioniert nur wenn ein multiroom verbund vorhanden ist, ansonsten kommt kp was raus var CurrentTrackOnCurrentPi = getState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'title').val var CurrentAlbumOnCurrentPi = getState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'album').val var CurrentServiceOnCurrentPi = getState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'service').val var CurrentStatusOnCurrentPi = getState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'status').val if(String(value).toLowerCase().includes('multiroom') == false){ // Fall 1: Sender //vergleichen ob ein anderer PI das gleiche abspielt und in multiroom betrieb ist, dann ist pi == mother var CurrentSender = '' var CurrentSenderID = parseInt(99) var CurrentReceiver = '' var CurrentReceiverID = parseInt(99) for (ID_VolumioSearch in Volumios){ if(ID_VolumioSearch != ID_Volumio){ var CurrentTrackOnOtherPi = getState(Folder + String(parseInt(ID_VolumioSearch)) + '.playbackInfo.' + 'title').val var CurrentAlbumOnOtherPi = getState(Folder + String(parseInt(ID_VolumioSearch)) + '.playbackInfo.' + 'album').val var CurrentServiceOnOtherPi = getState(Folder + String(parseInt(ID_VolumioSearch)) + '.playbackInfo.' + 'service').val var CurrentStatusOnOtherPi = getState(Folder + String(parseInt(ID_VolumioSearch)) + '.playbackInfo.' + 'status').val if (CurrentStatusOnCurrentPi == CurrentStatusOnOtherPi && CurrentTrackOnCurrentPi == CurrentTrackOnOtherPi && CurrentServiceOnOtherPi == 'multiroom'){ // == -> ID_Volumio = mother; ?? -> receiver CurrentSender = Volumios[ID_Volumio] CurrentSenderID = parseInt(ID_Volumio) CurrentReceiver = Volumios[ID_VolumioSearch] CurrentReceiverID = parseInt(ID_VolumioSearch) // log('CurrentServiceRefreshed: ' + Volumios[ID_Volumio]) //nochmals gegenprüfen ob son von möglichen müttern auch auf anderen wiedergegeben wird! //nur schreiben wenn sich was ändert!!!! und auch zurücksetzen setStateOnlyIfDifferent(Folder + String(parseInt(CurrentReceiverID)) + '.playbackInfo.' + 'multiroom',true) setStateOnlyIfDifferent(Folder + String(parseInt(CurrentSenderID)) + '.playbackInfo.' + 'multiroom',true) setStateOnlyIfDifferent(Folder + String(parseInt(CurrentSenderID)) + '.playbackInfo.' + 'multiroomSender',true) setStateOnlyIfDifferent(Folder + String(parseInt(CurrentReceiverID)) + '.playbackInfo.' + 'multiroomReceiver',true) setStateOnlyIfDifferent(Folder + String(parseInt(CurrentReceiverID)) + '.playbackInfo.' + 'multiroomReceivingFromID',CurrentSenderID) setStateOnlyIfDifferent(Folder + String(parseInt(CurrentReceiverID)) + '.playbackInfo.' + 'multiroomReceivingFromName',CurrentSender) //und in abfrage abfangen, dass diese infos nicht gesetzt werden wenn er receiver ist if(getState(Folder + String(parseInt(CurrentReceiverID)) + '.playbackInfo.' + 'status').val == 'play'){ setStateOnlyIfDifferent(Folder + String(parseInt(CurrentReceiverID)) + '.playbackInfo.' + 'multiroomPlaying', true) }else{ setStateOnlyIfDifferent(Folder + String(parseInt(CurrentReceiverID)) + '.playbackInfo.' + 'multiroomPlaying', false) } if(getState(Folder + String(parseInt(CurrentSenderID)) + '.playbackInfo.' + 'status').val == 'play'){ setStateOnlyIfDifferent(Folder + String(parseInt(CurrentSenderID)) + '.playbackInfo.' + 'multiroomPlaying', true) }else{ setStateOnlyIfDifferent(Folder + String(parseInt(CurrentSenderID)) + '.playbackInfo.' + 'multiroomPlaying', false) } }else{ } } } if(CurrentSender == '' || CurrentSenderID == parseInt(99)){ setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomSender', false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomPlaying', false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceiver',false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceiver',false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceiver',false) } if(CurrentReceiver == ''){} if(CurrentReceiverID == parseInt(99)){} }else if(String(value).toLowerCase().includes('multiroom')){ setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomSender',false) }else{ } var ID_ReceivingTemp = parseInt(getState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceivingFromID').val) if(ID_ReceivingTemp != 99 ){ var ID_ReceivingTempTitle = getState(Folder + String(ID_ReceivingTemp) + '.playbackInfo.' + 'title').val var ID_ReceivingTempStatus = getState(Folder + String(ID_ReceivingTemp) + '.playbackInfo.' + 'status').val }else{ var ID_ReceivingTempTitle = 'TempValue' var ID_ReceivingTempStatus = 'TempValue' } //wenn gleich multiroom aber pla state/titel ungleich motherid oder wenn state ungleich multiroom und PI ist kein Sender if(ID_ReceivingTemp != 99){ if(CurrentServiceOnCurrentPi == 'multiroom' && (CurrentTrackOnCurrentPi != ID_ReceivingTempTitle ||CurrentStatusOnCurrentPi != ID_ReceivingTempStatus)){ setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroom', false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomSender', false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomPlaying', false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceiver',false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceivingFromID',99) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceivingFromName','') } } if (CurrentServiceOnCurrentPi != 'multiroom' && ID_Volumio != CurrentSenderID && ID_Volumio != CurrentReceiverID){ setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroom',false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroom',false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceiver',false) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceivingFromID',99) setStateOnlyIfDifferent(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + 'multiroomReceivingFromName','') } // ------------------ Multiroom Handling v2 --------------------------------------- } // set default volume, e.g. after reboot if ((value == "" || value == undefined || value == "undefined") && (value!=0||value!="0")){ value = "notAvailable" //handling dass 0 nicht als null interpretiert wird.... if(field == 'volume'){ switch(parseInt(ID_Volumio)) { case 0: // rStream value = 20 break; case 1: // workStream value = 28 break; case 2: // kitchenStream value = 32 break; case 3: // flurStream value = 35 break; default: value = 20 // } } } // Handling wenn wert "notAvailable" und state ist typ number -> value = 0 statt "notAvailable" var TypeOfState = getObject(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field).common.type //logs hierfür in if weiter unten! sonst logt er bei jedem refresh if(TypeOfState == 'number' && value == 'notAvailable'){ // log('ERROR') value = 0 } if(TypeOfState == 'boolean' && value == 'notAvailable'){ // log('ERROR') value = false } if(TypeOfState == 'string' && (value === false || value === true)){ // log('ERROR') value = String(value) } //nur setzen wenn es eine änderung gab if(getState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field).val != value){ setState(Folder + String(parseInt(ID_Volumio)) + '.playbackInfo.' + field,value) if(field == 'stream'){ } } } } if(command == "getQueue"){ log(result) } if(command == "getzones"){ zones = extract(result,'zones') for (i in zones){ log(zones[i]) log(i) } log(result) } if(command == "collectionstats"){ log(result) } if(command == "pushNotificationUrls"){ log(result) } if(command == "ping"){ log(result) } if(command == "getSystemVersion"){ log(result) } if(command == "getSystemInfo"){ log(result) } }).on("error", function (e) { // returnValue = "ERROR" //console.error(e); }); return; } catch (e) { // returnValue = "ERROR"; //console.error(e); return; } } } function setStateOnlyIfDifferent(ObjectID,NewValue){ var CurrentValue = getState(ObjectID).val if(CurrentValue != NewValue){ setState(ObjectID,NewValue) } } function getIDVolumioForInfos(objID){ var PlayerName = objID.split(".")[objID.split('.').length-4].split('_') return PlayerName[PlayerName.length-1] } function getIDofState(objID){ return objID.split(".")[objID.split('.').length-1] } function getIDVolumio(objID){ var PlayerName = objID.split(".")[objID.split('.').length-3].split('_') return PlayerName[PlayerName.length-1] } function getIDVolumio_noSubfolder(objID){ var PlayerName = objID.split(".")[objID.split('.').length-2].split('_') return PlayerName[PlayerName.length-1] } function getVolumioStates(Volumios_IPs){ for (ID_Volumio in Volumios_IPs){ restapiRequest('192.168.178.' + Volumios_IPs[ID_Volumio],"getState",ID_Volumio) } } function httpRequest_wo_return(URL){ try { require("request")(URL).on("error", function (e) {console.error(e);}); } catch (e) { console.error(e); } }
Hier ein zweites Skript, welches nur States erzeugt welche ich für meine vis benötige und Icons für iQontrol setzt.
var var_saver ={} var names = ['Volumio_Player_0','Volumio_Player_1','Volumio_Player_2','Volumio_Player_3'] // Länge von names muss identisch mit Volumios sein, zahlen von 0 aus hochzählend var Volumios = ["rStream","workStream","kitchenStream","flurStream"] //muss in beiden Skripten identisch sein for (var sd in names) { var Audio_Infos_ID = "javascript.0.Allgemeine_Variablen.Player."+names[sd]+".Infos.Audio." var_saver[sd]= { "Audio_Infos_ID": Audio_Infos_ID, "CoverURL": Audio_Infos_ID+"CoverArt", "ID_Source_SampleRate": Audio_Infos_ID+"Source_SampleRate", "ID_Source_bitdeepth": Audio_Infos_ID+"Source_bitdeepth", "ID_Source_bitdeepthDisplay": Audio_Infos_ID+"Source_bitdeepthDisplay", "ID_Source_Channels": Audio_Infos_ID+"Source_Channels", "ID_HiRes_Audio": Audio_Infos_ID+"HiRes_Audio", "ID_Source_SampleRateDisplay": Audio_Infos_ID+"Source_SampleRateDisplay", } createState(var_saver[sd]["CoverURL"],{role:"state",name:"CoverArt from Moodeaudio and mpd adapter"}) createState(var_saver[sd]["ID_Source_SampleRateDisplay"], 0, {role: "state","type": "string","unit": "kHz","read": true,"write": true,name: 'Abtastfrequenz der Quelldatei'}) createState(var_saver[sd]["ID_Source_SampleRate"], 0, {role: "state","type": "number","unit": "Hz","read": true,"write": true,name: 'Abtastfrequenz der Quelldatei'}) createState(var_saver[sd]["ID_Source_bitdeepth"], 0, {role: "state","type": "number","unit": "bit","read": true,"write": true,name: 'Bittiefe der Quelldatei'}) createState(var_saver[sd]["ID_Source_bitdeepthDisplay"], 0, {role: "state","type": "string","unit": "","read": true,"write": true,name: 'Bittiefe der Quelldatei'}) createState(var_saver[sd]["ID_Source_Channels"], 0, {role: "state","type": "number","read": true,"write": true,name: 'Audiokanaele der Quelldatei'}) createState(var_saver[sd]["ID_HiRes_Audio"], {role: "state","type": "boolean","read": true,"write": true,name: 'HiRes Anzeige'}) //listener to change high res iQontrol icon on({id: var_saver[sd]["ID_HiRes_Audio"], change: 'ne'}, function (obj) { // volume_up var value = obj.state.val; var Verursacher = obj.id; var StateName = getIDofState(obj.id) var ID_Volumio_Verursacher = getIDVolumioForInfos(obj.id) // set iQontrol icon if(value === true){ //do something //setiQontrolIcon("HiRes" + Volumios[ID_Volumio_Verursacher],'Icon_HiResAudio-48',"si") //funktion poste ich bei Interesse } if(value === false){ //do something //setiQontrolIcon("HiRes" + Volumios[ID_Volumio_Verursacher],'blank',"blank") //funktion poste ich bei Interesse } }); } function getIDVolumioForInfos(objID){ var PlayerName = objID.split(".")[objID.split('.').length-4].split('_') return PlayerName[PlayerName.length-1] } function getIDofState(objID){ return objID.split(".")[objID.split('.').length-1] }
und hier noch weitere, vllt nützliche, Funktionen (bei mir global definiert)
function getVolumiosReceiving(VolumiosReceiving,ReturnID){ //VolumiosReceiving muss ein array sein, kann auch leer sein! //ermitteln welche volumios receiver sind un didese zu ignored deviced hinzufügen var Counter = Array.apply(null, Array(15)).map(function (x, i) { return i; }) for(ID in Counter){ if(existsObject('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID)){ // log(ID) var Receiving = getState('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID + '.playbackInfo.multiroomReceiver').val if(Receiving){ if(ReturnID){ VolumiosReceiving.push(ID) }else{ VolumiosReceiving.push('Volumio_Player_' + ID) } } }else{ break; } } return VolumiosReceiving } function getVolumiosSending(VolumiosSending,ReturnID){ //VolumiosSending muss ein array sein, kann auch leer sein! //ermitteln welche volumios receiver sind un didese zu ignored deviced hinzufügen var Counter = Array.apply(null, Array(15)).map(function (x, i) { return i; }) for(ID in Counter){ if(existsObject('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID)){ // log(ID) var Sending = getState('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID + '.playbackInfo.multiroomSender').val if(Sending){ if(ReturnID){ VolumiosSending.push(ID) }else{ VolumiosSending.push('Volumio_Player_' + ID) } } }else{ break; } } return VolumiosSending } function getVolumiosPlaying(VolumiosPlaying,ReturnID){ //VolumiosPlaying muss ein array sein, kann auch leer sein! //ermitteln welche volumios receiver sind un didese zu ignored deviced hinzufügen var Counter = Array.apply(null, Array(15)).map(function (x, i) { return i; }) for(ID in Counter){ if(existsObject('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID)){ // log(ID) var StatusVolumio = getState('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID + '.playbackInfo.status').val if(StatusVolumio == 'play' || StatusVolumio == "play"){ var Playing = true }else{ var Playing = false } if(Playing){ if(ReturnID){ VolumiosPlaying.push(ID) }else{ VolumiosPlaying.push('Volumio_Player_' + ID) } } }else{ break; } } return VolumiosPlaying } function getVolumiosStatus(VolumiosStatus){ //VolumiosStatus muss ein array sein, kann auch leer sein! //ermitteln welche volumios receiver sind un didese zu ignored deviced hinzufügen var Counter = Array.apply(null, Array(15)).map(function (x, i) { return i; }) for(ID in Counter){ if(existsObject('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID)){ // log(ID) var StatusVolumio = getState('javascript.0.Allgemeine_Variablen.Player.Volumio_Player_' + ID + '.playbackInfo.status').val VolumiosStatus.push(StatusVolumio) }else{ break; } } return VolumiosStatus }
Ich hab selber leider nicht nicht die Zeit gefunden das Skript vollständig auszukommentieren. Das Skript ist sicher nicht perfekt, sei es Ressourcentechnisch oder auch von der Umsetzung. Aber ich hoffe es hilft dir/euch trotzdem weiter.
Für Fragen/Support steh ich gerne zur Verfügung
Anbei noch Screenshots:
-
@muellerra hey, wieder was zum spielen!
werd mal wieder reinlinsen... -
@muellerra hmm, instanz wieder mal gestartet. mal komplett deinstalliert, jetzt neu 0.1.3.
aber nach wie vor:
somit wird mal nix aktualisiert bei einem senderwechsel bei internetradio.
da werden auch die scripts nichts ändern. -
@da_woody Hi, ich glaube ich hab das vergessen zu erwähnen. Mit dem Skript wird der Adapter nicht mehr benötigt. Ich hab mir das mal als alternative zu dem volumio adapter geschrieben.
-
@muellerra AHA! na dann mal schauen wenn ich zeit finde...
kommt ja auch noch dazu:
-
@muellerra so, hab jetzt rumgebastelt. in meiner sturheit latürnich einen eigenen ordner gemacht. in iQontrol auch schon geändert.
soweit alles geändert, fehler in zeile 9 gefunden, war } statt]... kann mir ja halbwegs helfen.
allerdings bekomm ich in 362 einen geklatscht, den ich nicht packe. kannst da mal reinlinsen? hab ja nur einen raspi dran, sollte aber mit den änderungen passen.
Volumio.txt
-
@da_woody Hi, schau mal in Zeile 362 ans Ende, da hab ich vergessen ein
/
zu entfernen...
Habs auch gleich im ursprünglichen post angepasst -
@muellerra dachte ich mir, allerdings bin ich nicht so weit drinnen beim proggen.
Der Rest passt bei meinen Änderungen?
Werden durch den Fehler die DPs nicht komplett angelegt? -
@da_woody ich habs mal kurz gedifft, deine Änderungen sollten ja nur die IP-Adressen und der Ordner sein. Das passt.
@da_woody sagte in Volumio adapter?:
Werden durch den Fehler die DPs nicht komplett angelegt?
lass das Skript am besten 2 mal (erfolgreich) durchlaufen. Dann sind aufjedenfall die DP alle erstellt und die event listener alle scharf.
Ich habs mal kurz mit einem Volumio durchgetestet, sollte alles auch mit einem Volumio funktionieren. Lediglich "Multiroom Features" könnte es sein dass "Müll" in die DP geschrieben wird. aber bei nur einem Volumio sollte das egal sein, im Zweifel einfach die setState auskommentieren.
-
@muellerra den Namen hab ich auch auf Studio geändert. Tögal.
Mach ich nachher, bin grad auf ein gutes AbendBier im Stammlokal.
Multitasking, ioB, 3D-Drucken, im Kopf noch Planung für Kanten Abdeckungen für die Wandvertafelung zuschneiden und fräsen... -
@muellerra autsch...
19:19:22.367 info javascript.0 (521) Start javascript script.js.common.Volumio.Volumio 19:19:22.392 info javascript.0 (521) script.js.common.Volumio.Volumio: registered 22 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions 19:19:25.887 warn javascript.0 (521) at restapiRequest (script.js.common.Volumio.Volumio:601:8) 19:19:25.887 warn javascript.0 (521) at Object.getVolumioStates (script.js.common.Volumio.Volumio:942:9) 19:19:26.387 warn javascript.0 (521) at restapiRequest (script.js.common.Volumio.Volumio:601:8) 19:19:26.387 warn javascript.0 (521) at Object.getVolumioStates (script.js.common.Volumio.Volumio:942:9) 19:19:26.887 warn javascript.0 (521) at restapiRequest (script.js.common.Volumio.Volumio:601:8) 19:19:26.887 warn javascript.0 (521) at Object.getVolumioStates (script.js.common.Volumio.Volumio:942:9) 19:19:27.387 warn javascript.0 (521) at restapiRequest (script.js.common.Volumio.Volumio:601:8) 19:19:27.387 warn javascript.0 (521) at Object.getVolumioStates (script.js.common.Volumio.Volumio:942:9) 19:19:27.889 warn javascript.0 (521) at restapiRequest (script.js.common.Volumio.Volumio:601:8) 19:19:27.889 warn javascript.0 (521) at Object.getVolumioStates (script.js.common.Volumio.Volumio:942:9) 19:19:28.391 warn javascript.0 (521) at restapiRequest (script.js.common.Volumio.Volumio:601:8) 19:19:28.391 warn javascript.0 (521) at Object.getVolumioStates (script.js.common.Volumio.Volumio:942:9) 19:19:28.890 warn javascript.0 (521) at restapiRequest (script.js.common.Volumio.Volumio:601:8) 19:19:28.890 warn javascript.0 (521) at Object.getVolumioStates (script.js.common.Volumio.Volumio:942:9) 19:19:29.011 info javascript.0 (521) Stop script script.js.common.Volumio.Volumio
ok, da dürfte was nicht passen... rrBroker gibts bei mir ja nicht.
if(getState('ping.1.rrBroker.' + Volumios[ID_Volumio]).val){
warum allerdings 942 motzt...