@Gringo @smai
Hallo SmartVISU Freunde…
Habe seit längerem wieder einmal Zeit und versuche mich gerade an einem neuen Projekt.
Ich würde gerne mein Sonos System über die SmartVISU mit IOBroker steuerbar machen.
Ich habe hier auch ein tolles Widget von ddtlabs gefunden https://github.com/ddtlabs/smartvisu-wi … ster/sonos
das aber allerdings für FHEM in Verbindung mit dem Fronthem Treiber geschrieben wurde.
[image: 4007_sonos.png]
Ich habe das Widget einmal testweise in die SmartVISU 2.9 eingebunden habe aber jetzt keine Ahnung, wo ich jetzt die Datenpunkte aus IOBroker in der html. des Widgets einsetzen muss.
/**
____
_ _ / ___| ___ _ __ ___ ___ _ _
(_) (_) \___ \ / _ \ | '_ \ / _ \ / __| (_) (_)
_ _ ___) | | (_) | | | | | | (_) | \__ \ _ _
(_) (_) |____/ \___/ |_| |_| \___/ |___/ (_) (_)
*/
/** ----------------------------------------------------------------------------
* Sonos(r,c) Multimedia Player
*
* @param id: unique id for this widget, no default, mandatory
* @param gad: gad name, no default, mandatory
* @param neighbors: array of other Sonos neighbour speakers. eg: ['Sonos_Studio', 'Sonos_Wohnzimmer'], no default, optional
* @param radiolist_header: header for radio list
* @param playlist_header: header for play list
*
* @author and copyright dev0
------------------------------------------------------------------------------*/
{% macro player(id, gad, neighbors) %}
/** set your preferences here */
{% set prefix = 'mm_' %} /** prefix used for all gad items */
{% set text_volume = 'Volume of neighbors'%} /** description within neighbors popup */
{% set radiolist_header = 'Radios' %} /** radiolist button title */
{% set playlist_header = 'Playlists' %} /** playlist button title */
/** do not modify anything below, as long as you know what you are dong */
{% set version = '0.91'%}
{% set defCoverArtUrl = 'pages/base/pics/sonos_empty.jpg' %}
{% set uid = uid(page, id) %}
{% set gad = prefix~gad %} /** use 'Direct' converter in GAD editor */
{% set state = '.state' %} /** use 'Direct' converter in GAD editor */
{% set volume = '.volume' %} /** use 'Direct' converter in GAD editor */
{% set artist = '.currentArtist' %} /** use 'Direct' converter in GAD editor */
{% set title = '.currentTitle' %} /** use 'Direct' converter in GAD editor */
{% set album = '.currentAlbum' %} /** use 'Direct' converter in GAD editor */
{% set trackDuration = '.currentTrackDuration' %} /** use 'Direct' converter in GAD editor */
{% set radioSender = '.currentSender' %} /** use 'Direct' converter in GAD editor */
{% set radioShow = '.currentSenderCurrent' %} /** use 'Direct' converter in GAD editor */
{% set radioInfo = '.currentSenderInfo' %} /** use 'Direct' converter in GAD editor */
{% set mute = '.Mute' %} /** use 'Direct' converter in GAD editor */
{% set repeat = '.Repeat' %} /** use 'Direct' converter in GAD editor */
{% set shuffle = '.Shuffle' %} /** use 'Direct' converter in GAD editor */
{% set playlist = '.Playlist' %} /** use 'Direct' converter in GAD editor */
{% set radiolist = '.Radiolist' %} /** use 'Direct' converter in GAD editor */
{% set loudness = '.Loudness' %} /** use 'Direct' converter in GAD editor */
{% set crossfade = '.CrossfadeMode' %} /** use 'Direct' converter in GAD editor */
{% set addMember = '.AddMember' %} /** use 'Direct' converter in GAD editor */
{% set remMember = '.RemoveMember' %} /** use 'Direct' converter in GAD editor */
{% set bass = '.Bass' %} /** use 'Direct' converter in GAD editor */
{% set treble = '.Treble' %} /** use 'Direct' converter in GAD editor */
{% set balance = '.Balance' %} /** use 'Direct' converter in GAD editor */
{% set roomName = '.roomName' %} /** use 'Direct' converter in GAD editor */
{% set isInAnyGroup = '.svIsInAnyGroup' %} /** Coverter: SonosGroup */
{% set hasClient = '.svHasClient' %} /** Coverter: SonosGroup */
{% set trackPos = '.svTrackPosition' %} /** Coverter: SonosTrackPos */
{% set coverUrl = '.currentAlbumArtURL' %} /** Coverter: SonosAlbumArtURL */
{% set transportStateStop = '.svTransportStateStop' %} /** Coverter: SonosTransportState */
{% set transportStatePlay = '.svTransportStatePlay' %} /** Coverter: SonosTransportState */
{% set transportStatePause = '.svTransportStatePause' %} /** Coverter: SonosTransportState */
{% import "basic.html" as basic %}
{% import "widget_ddtlabs_sonos.html" as ddtlabs_int_sonos %}

{{ ddtlabs_int_sonos.slider(id~volume, gad~volume, 0, 100, 1, 'bottomup') }}
|
{{ ddtlabs_int_sonos.cover(id~coverUrl, gad~coverUrl, defCoverArtUrl) }}
{{ basic.slider(id~trackPos, gad~trackPos, 0, 100, 1) }}
{{ basic.symbol(id~gad~transportStatePause~Symbol, gad~transportStatePause, '', 'audio_pause.svg', '1', '', 'red') }}
|
{{ basic.value(id~radioSender, gad~radioSender, '', '') }}
{{ basic.value(id~artist, gad~artist, '', '') }}
|
{{ basic.value(id~radioInfo, gad~radioInfo, '', '') }}
{{ basic.value(id~album, gad~album, '', '') }}
|
{{ basic.value(id~radioShow, gad~radioShow, '', '') }}
{{ basic.value(id~title, gad~title, '', '') }}
|
{{ ddtlabs_int_sonos.selectmenu(id~'playlist', gad~playlist, playlist_header) }}
|
{{ ddtlabs_int_sonos.selectmenu(id~'radiolist', gad~radiolist, radiolist_header) }}
|
|
{% for neighbor in neighbors%}
{% endfor %}
{{ basic.dual(id~gad~isInAnyGroup, gad~isInAnyGroup, 'my_audio_group_empty.svg', 'my_audio_group_fault.svg', '1', '0', 'mini') }}
|
{{ basic.dual(id~addMember~'.'~neighbor, gad~hasClient~'_'~neighbor, 'my_audio_group_'~neighbor~'.svg', 'my_audio_group_'~neighbor~'.svg', '1', '0') }}
|
[](#{{id}}ddtlabs_sonos_popup)
[Close](#)
Sonons Widget v{{version}}
{% for neighbor in neighbors%}
{% endfor %}
| Sonos {{ basic.value(id~gad~roomName, gad~roomName, '', '') }}: |
| Bass | {{ basic.slider(id~bass, gad~bass, -10, 10, 1, '') }} |
| Treble | {{ basic.slider(id~gad~treble, gad~treble, -10, 10, 1, '') }} |
| Balance | {{ basic.slider(id~gad~balance, gad~balance, -100, 100, 1, '') }} |
| |
| {{text_volume}}: |
{{ basic.value(id~prefix~neighbor~roomName, prefix~neighbor~roomName, '', '') }} |
{{ ddtlabs_int_sonos.slider(id~prefix~neighbor~'volumePop', prefix~neighbor~volume, 0, 100, 1, '') }} |
|
|
{{ basic.dual(id~mute, gad~mute, 'audio_volume_mute.svg', 'audio_volume_mid.svg', 1, 0, 'mini') }}
|
{{ basic.button(id~'_prev', gad~state, 'Prev', 'control_arrow_left.svg', 'Previous') }}
{{ basic.dual(id~gad~'_playX', gad~transportStatePlay, 'audio_play.svg', 'audio_play.svg', '1', '0', '') }}
{{ basic.dual(id~gad~'_stopX', gad~transportStateStop, 'audio_stop.svg', 'audio_stop.svg', '1', '0', '') }}
{{ basic.button(id~'_next', gad~state, 'Next', 'control_arrow_right.svg', 'Next') }}
|
{{ basic.dual(id~repeat, gad~repeat, 'audio_repeat.svg', 'audio_repeat.svg', 1, '0') }}
|
{{ basic.dual(id~shuffle, gad~shuffle, 'audio_shuffle.svg', 'audio_shuffle.svg', 1, '') }}
|
{{ basic.dual(id~loudness, gad~loudness, 'audio_loudness.svg', 'audio_loudness.svg', 1, 0, 'mini') }}
|
{{ basic.dual(id~crossfade, gad~crossfade, 'audio_fade.svg', 'audio_fade.svg', 1, 0, 'mini') }}
|
|
{% endmacro %}
/** ----------------------------------------------------------------------------
* Display cover/logo
*
* @param id: unique id
* @param src: url to image
* @param prefix: should be emtpy
------------------------------------------------------------------------------*/
{% macro cover(id, src, defCoverArtUrl) %}

{% endmacro %}
/** ----------------------------------------------------------------------------
* Selectmenu_static for status.collopse
*
* @param id: unique id for this widget
* @param gad: gad for this widget
* @param items: array of playlists
* @param label: lable for this widget
------------------------------------------------------------------------------*/
{% macro selectmenu_static(id, gad, items, label, selected, urlencode) %}
<a class="ui-btn-inline ui-mini selectmenu"><select name="{{ uid(page, id) }}" id="{{ uid(page, id) }}" data-widget="ddtlabs_sonos.selectmenu_static" data-item="{{ gad }}" data-native-menu="false" data-placeholder="false" data-mini="true" class="selectmenu">{% for item in items %}
{% if urlencode %}
<option value="{{ item[1]|url_encode }}">{{ item[0] }}</option>
{% else %}
<option value="{{ item[1] }}">{{ item[0] }}</option>
{% endif %}
{% endfor %}
<option selected="">{{ selected }}</option></select></a>
{% endmacro %}
/** ----------------------------------------------------------------------------
* Selectmenu for Playlists/Radios
*
* @param id: unique id for this widget
* @param gad: gad for this widget
* @param label: lable for this widget
* @thanx to raman (https://forum.fhem.de/index.php/topic,54768.0.html)
------------------------------------------------------------------------------*/
{% macro selectmenu(id, gad, label) %}
<a class="ui-btn-inline ui-mini select"></a>
{% endmacro %}
/** ----------------------------------------------------------------------------
* Displays a slider-control
*
* @param unique id for this widget
* @param a item
* @param the minimum value if the slider is moved to total left (optional, default 0)
* @param the maximum value if the slider is moved to total right (optional, default 255)
* @param step between two values (optional, default 5)
* @param the orientation ('none', 'vertical', 'bottomup', 'semicircle')
* @info modified: 800ms delay for volume slider
------------------------------------------------------------------------------*/
{% macro slider(id, item, min, max, step, mode) %}
{% endmacro %}
/** ----------------------------------------------------------------------------
* Displays a presence button
*
* @param id: unique id for this widget
* @param player: player name
* @param prefix: prefix for playername
* @param color_present: color for present state
* @param color_absent: color for absent state
------------------------------------------------------------------------------*/
{% macro presence(id, player, prefix, color_present, color_absent) %}
{% import "basic.html" as basic %}
{% set prefix = prefix|default('mm_') %}
{% set color_present = color_present|default('black') %}
{% set color_absent = color_absent|default('red') %}
{{ basic.symbol('id_'~id~'_present', prefix~player~'.presence', '', 'control_clear.svg', 'appeared', '', color_present) }}
{{ basic.symbol('id_'~id~'_absent', prefix~player~'.presence', '', 'control_on_off.svg', 'disappeared', '', color_absent) }}
{{ basic.symbol('id_'~id~'_notLoaded', prefix~player~'.presence', '', 'control_on_off.svg', '~~NotLoadedMarker~~', '', color_absent) }}
{% endmacro %}
Das Widget wird mit folgendem Code als Block in der SmartVISU dargestellt:
{% import "widget_ddtlabs_sonos.html" as ddtlabs_sonos %}
### Sonos Studio {{ ddtlabs_sonos.presence('sonos_studio', 'Sonos_Studio') }}
|
{{ ddtlabs_sonos.player('sonos_studio', 'Sonos_Studio', ['Sonos_Kitchen', 'Sonos_Wohnzimmer']) }}
|
### Sonos Wohnzimmer {{ ddtlabs_sonos.presence('sonos_wohnzimmer', 'Sonos_Wohnzimmer') }}
|
{{ ddtlabs_sonos.player('sonos_wohnzimmer', 'Sonos_Wohnzimmer', ['Sonos_Kitchen', 'Sonos_Studio']) }}
|
### Sonos Kitchen {{ ddtlabs_sonos.presence('sonos_kitchen', 'Sonos_Kitchen') }}
|
{{ ddtlabs_sonos.player('sonos_kitchen', 'Sonos_Kitchen', ['Sonos_Wohnzimmer', 'Sonos_Studio']) }}
|
/** Note: radio stations must be added to Sonos "My Radiostations" to work with FHEM's Sonos Modules */
Was ich in der Anleitung von ddtlabs noch nicht ganz verstehe, was mit der "Widget declaration" gemeint ist:
/**
* Sonos(r) Multimedia Player
*
* @param id: unique id for this widget, no default, mandatory
* @param gad: gad name, no default, mandatory
* @param neighbors: array of other Sonos neighbour speakers. eg: ['Sonos_Studio', 'Sonos_Wohnzimmer'], no default
* @author dev0
*/
{% macro player(id, gad, neighbors) %}
Wo oder auf welcher Seite muss das eingefügt werden?
Generell gefragt, geht das überhaupt so, wie ich mir das vorstelle oder bin ich da total auf dem Holzweg und würde das nur mit Frothem und FHEM funktionieren?
Bekommt man das irgendwie auf IOBroker umgebaut?
Ich danke euch mal wieder für jede Hilfe :-)
Gruß
Jochen