[Neues Modul] BOSE SoundTouch

Begonnen von dominik, 05 Januar 2016, 22:28:40

Vorheriges Thema - Nächstes Thema

dominik

Das Modul ist ab sofort im offiziellen FHEM Repository. Bitte beachtet die benötigten Perl Libraries vor Verwendung.

Hallo zusammen,

hier ein neues Modul zur Steuerung der BOSE SoundTouch Familie. Die unterstützten Features können dem Changelog unten entnommen werden.

Folgende Libraries werden benötigt:
sudo apt-get install libwww-perl libmojolicious-perl libxml-simple-perl libnet-bonjour-perl libev-perl libdigest-perl-md5-perl
libmojolicious-perl muss >=5.54 sein, unter wheezy steht nur 2.x zur Verfügung. In so einem Fall kann über
sudo apt-get install cpanminus
sudo cpanm Mojolicious
die aktuellste Version installiert werden.

define bose_system BOSEST
Nach einer Minute erscheinen die Player unter "Unsorted"

Einrichtung TTS
sudo apt-get install libexif-dev libjpeg-dev libflac-dev libvorbis-dev libsqlite3-dev libavformat-dev libid3tag0-dev
sudo apt-get build-dep minidlna
mkdir minidlna
cd minidlna
git clone git://git.code.sf.net/p/minidlna/git minidlna-git
cd minidlna-git
./autogen.sh && ./configure && make (wenn ihr hier Fehler habt, dann bitte posten)
sudo make install

/etc/minidlna.conf (alles andere default!)
media_dir=/var/lib/minidlna
port=8200
serial=681....
album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg
album_art_names=AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg
album_art_names=Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg


/etc/init.d/minidlna
#!/bin/sh
#
# MiniDLNA initscript
#
# Based on the mediatomb debian package.
# Original authors: Tor Krill <tor@excito.com>
#                   Leonhard Wimmer <leo@mediatomb.cc>
#                   Andres Mejia <mcitadel@gmail.com>
#
# Modified by: Benoît Knecht <benoit.knecht@fsfe.org>
#
### BEGIN INIT INFO
# Provides:          minidlna
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop::    $network $local_fs $remote_fs
# Should-Start:      $all
# Should-Stop:       $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start minidlna at boot time
# Description:       Manage the minidlna daemon, a DLNA/UPnP-AV media server.
### END INIT INFO

unset USER

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin
DESC="DLNA/UPnP-AV media server"
NAME=minidlna
DAEMON=/usr/local/sbin/minidlnad
PIDDIR=/run/$NAME
PIDFILE=$PIDDIR/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
DEFAULT=/etc/default/$NAME

# Exit if the package is not installed
[ -x $DAEMON ] || exit 0

# Read configuration variable file if it is present
[ -r $DEFAULT ] && . $DEFAULT

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# Do not start the daemon if NO_START is enabled in DEFAULT
if [ "$START_DAEMON" != "yes" ] && [ "$1" != "stop" ]; then
        log_warning_msg "$NAME: Not starting $DESC."
        log_warning_msg "$NAME: Disabled in $DEFAULT."
        exit 0
fi

# Set the default configuration file
if [ -z $CONFIGFILE ]; then
        CONFIGFILE=/etc/minidlna.conf
fi

# Set the default log file
if [ -z $LOGFILE ]; then
        LOGFILE=/var/log/minidlna.log
fi

# Run as `minidlna' if USER is not specified or is `root'
if [ -z $USER ]; then
        USER=minidlna
fi

# If no group is specified, use USER
if [ -z $GROUP ]; then
        GROUP=$USER
fi

DAEMON_ARGS="-f $CONFIGFILE -P $PIDFILE $DAEMON_OPTS"

#
# Function that starts the daemon/service
#
do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        touch $LOGFILE && chown $USER:$GROUP $LOGFILE || return 2
        if [ ! -d $PIDDIR ]; then
            mkdir $PIDDIR || return 2
        fi
        chown $USER:$GROUP $PIDDIR || return 2

        start-stop-daemon --start --quiet --pidfile $PIDFILE \
                --chuid $USER:$GROUP --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE \
                --chuid $USER:$GROUP --exec $DAEMON -- \
                $DAEMON_ARGS \
                || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --exec $DAEMON
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2
        # Wait for children to finish too if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2
        # Many daemons don't delete their pidfiles when they exit.
        rm -rf $PIDDIR
        return "$RETVAL"
}

#
# Function that signals log rotation to the daemon/service
#
do_rotate()
{
        start-stop-daemon --stop --quiet --signal USR1 --pidfile $PIDFILE --exec $DAEMON
}

case "$1" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
    do_start
    case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
  ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  status)
       status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                if [ "$1" = "force-reload" ]; then
                        # Rescan the collection
                        DAEMON_ARGS="$DAEMON_ARGS -R"
                fi
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  rotate)
        log_daemon_msg "Reopening log file $LOGFILE"
        do_rotate
        log_end_msg $?
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload|rotate}" >&2
        exit 3
        ;;
esac

:


Changelog
v1.5.6 - 20160611
- FEATURE: auto-zone, start zone-play if speakers are playing the same (contentItemLocation)
             attr <name> autoZone on (default: off)
- BUGFIX: set zone only from master device as slave devices might not always report the truth (known bug at BOSE)
- CHANGE: set zonemember_X to UDN instead of player name
- CHANGE: delete TTS files after 30 days
- CHANGE: reduce number of http calls after each discovery process
- CHANGE: reduce number of http calls for key presses

v1.5.5 - 20160510
- BUGFIX: fix unitiliazed value in handleDeviceByIp

v1.5.4 - 20160509
- FEATURE: restore volume when speaker goes online
             allows to power off the box completely without loosing
             previous volume settings
- BUGFIX: fix possible unitialized value
- BUGFIX: fix next which should be return
- BUGFIX: sometimes double-tap feature wasn't working due to BOSE not
           updating zones for slave speakers

v1.5.3 - 20160425
- FEATURE: support static IPs (should only be used if device can't be discovered)
            attr bose_system staticIPs 192.168.1.52,192.168.1.53
- FEATURE: support speak channel name (useful for SoundTouch w/o display)
            attr <name> speakChannel 1-6
            attr <name> speakChannel 2,3,5,6
- BUGFIX: retry websocket setup every 5s if it fails
- BUGFIX: update supportClockDisplay reading only on reconnect
- CHANGE: remove user attr from main device

v1.5.2 - 20160403
- FEATURE: support clock display (SoundTouch 20/30)
             set <name> clock enable/disable

v1.5.1 - 20160330
- CHANGE: updated documentation (again many thx to Miami!)
- FEATURE: support triple-tap (currently no function implemented: any ideas? :))
- CHANGE: change back channel even after speakOff
- BUGFIX: unitialized value fixed

v1.5.0
- FEATURE: support SetExtensions (on-for-timer,...)
- FEATURE: support TTS (TextToSpeach) via Google Translate
            set <name> speak "This is a test message"
- FEATURE: support volume control for TTS
            set <name> speak "This message has different volume" 30
- FEATURE: support different languages for TTS
            set <name> speak "Das ist ein deutscher Test" de
            set <name> speak "Das ist ein deutscher Test" 30 de
- FEATURE: support off (instead of resume) after TTS messages (restores only volume settings)
            set <name> speakOff "Music is going to switch off now. Good night." 30 en
- FEATURE: speak "not available" text on Google Captcha
            can be disabled by ttsSpeakOnError = 0
- FEATURE: set default TTS language via ttsLanguage attribute
- FEATURE: automatically add DLNA server running on the same
            server as FHEM to the BOSE library
- FEATURE: automatically add all DLNA servers to BOSE library
            requires autoAddDLNAServers = 1 attribute for "main" (not players!)
- FEATURE: reuse cached TTS files for 30 days
- FEATURE: set DLNA TTS directory via ttsDirectory attribute
- FEATURE: set DLNA TTS server via ttsDLNAServer attribute
            only needed if the DLNA server is not the FHEM server
- FEATURE: support ttsVolume for speak
            ttsVolume = 20 (set volume 20 for speak)
            ttsVolume = +20 (increase volume by 20 from current level)
- FEATURE: add html documentation (provided by Miami)
- FEATURE: support relative volume settings with +/-
            set <name> volume +3
            set <name> speak "This is a louder message" +10
- FEATURE: new reading "connectedDLNAServers" (blanks are replaced by "-")
- FEATURE: support add/remove DLNA servers to the BOSE library
            set <name> addDLNAServer RPi
            set <name> removeDLNAServer RPi
- FEATURE: add readings for channel_07-20
- FEATURE: support saveChannel to save current channel to channel_07-20
- FEATURE: support bass settings only if available (/bassCapabilities)
- FEATURE: support bluetooth only if available (/sources)
- FEATURE: support switch source to airplay (untested)
- BUGFIX: update zone on Player discovery
- BUGFIX: fixed some uninitialized variables
- CHANGE: limit recent_X readings to 15 max

v1.0.0
- FEATURE: support multi-room (playEverywhere, stopPlayEverywhere)
- FEATURE: show current zone members in readings
- FEATURE: support createZone <deviceID1>,<deviceID2>,...
- FEATURE: support addToZone <deviceID1>,<deviceID2>,...
- FEATURE: support removeFromZone <deviceID1>,<deviceID2>,...
- FEATURE: add "double-tap" multi-room feature
            double-tap (<1s) a hardware preset button to
            enable or disable the multi-room feature
- FEATURE: support bass settings
- FEATURE: support infoUpdated (e.g. deviceName change)
- FEATURE: support mute on/off/toggle
- FEATURE: support recent channel list
            set name recent X
            names for recent list entries are shown in readings
- FEATURE: support channel_07-20 by attribute
            format:name|location|source|sourceAccount or
                        name|location|source| if no sourceAccount
- FEATURE: support bluetooth/bt-discover/aux mode
- FEATURE: support ignoreDeviceIDs for main define
            format:B23C23FF,A2EC81EF
- CHANGE: reading channel_X => channel_0X (e.g. channel_02)

v0.9.7
- FEATURE: print module version on startup of main module
- FEATURE: support device rename (e.g. BOSE_... => wz_BOSE)
- FEATURE: show preset itemNames in channel_X reading
- FEATURE: automatically update preset readings on change
- FEATURE: add description reading (could be very long)
- CHANGE: change log level for not implemented events to 4
- CHANGE: use only one processXml function for websocket and http
- BUGFIX: fix set off/on more than once within 1 second
- BUGFIX: fix warnings during setup process
- BUGFIX: support umlauts in all readings
- BUGFIX: handle XMLin errors with eval
- BUGFIX: handle "set" when speaker wasn't found yet

v0.9.6
- FEATURE: support prev/next track

v0.9.5
- FEATURE: update channel based on websocket events
- BUGFIX: specify minimum libmojolicious-perl version
- BUGFIX: reconnect websocket if handshake fails
- BUGFIX: presence reading fixed
- CHANGE: websocket request timeout changed to 10s (prev. 5s)
- CHANGE: clockDisplayUpdated message handled now

v0.9.4
- CHANGE: completely drop ithreads (reduces memory usage)
- CHANGE: search for new devices every 60s (BlockingCall)
- CHANGE: check presence status based on websocket connection
- BUGFIX: removed arguments and readings for main BOSEST
- FEATURE: read volume on startup

v0.9.3
  - fix "EV does not work with ithreads."

v0.9.2
  - fix memory leak
  - use select instead of usleep

v0.9.1
  - bugfix for on/off support

v0.9
  - [b]autodiscover BOSE SoundTouch players: autocreate BOSE_<deviceID>[/b]
  - add alias for newly created devices
  - update IP if the player IP changes
  - automatically re-connect websocket
  - support UTF-8 names with umlauts
  - reconnect websocket when connection closed
  - add firmware version & IP readings
  - automatically update /info on IP update
  - state: offline,playing,stopped,paused,online (online means standby)
  - support on/off commands based on current state
  - add support more readings for now_playing

v0.2
- connect to websocket to receive speaker events (now playing, ...)
- support stop/play/pause/power
- change preset to channel according to DevGuidelinesAV
- read /info on startup

v0.1
- define BOSE Soundtouch based on fixed IP
- change volume via /volume
- change preset via /key

fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

UliM

Hi,
Coole Sache!
Wenn hier weiterentwickelt wird, wollte ich mal auf eine existierende Guideline für einheitliche Befehlssätze in allen fhem-Audio-Modulen aufmerksam machen, vielleicht kann man sich ja daran oriientieren:
http://www.fhemwiki.de/wiki/DevelopmentGuidelinesAV
'key' gibt es da bspw. nicht.

Gruß + viel Erfolg,
Uli
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

Sonic

Hallo Dominik,
ich freue mich das du damit angefangen hast, auch BOSE Soundtouch in FHEM als Modul aufzunehmen.

Leider kann ich nicht mit Programmieren, da ich wenig PEARL Kenntnisse habe.
Jedoch freue ich mich darauf als Nutzer davon zu profitieren.

vielen Dank schon mal

gruss
KLAUS

dominik

Zitat von: UliM am 06 Januar 2016, 04:26:08
Hi,
Coole Sache!
Wenn hier weiterentwickelt wird, wollte ich mal auf eine existierende Guideline für einheitliche Befehlssätze in allen fhem-Audio-Modulen aufmerksam machen, vielleicht kann man sich ja daran oriientieren:
http://www.fhemwiki.de/wiki/DevelopmentGuidelinesAV
'key' gibt es da bspw. nicht.

Gruß + viel Erfolg,
Uli
Hi Uli,
danke für die Info. Den Guide kannte ich noch nicht.
Keine Sorge 'key' ist nicht als Befehl gedacht, mit /key meinte ich nur den WebService (http://ip:8090/key) über welchen der Befehl an das BOSE System geschickt wird.

Werde dann bei der weiteren Implementierung die Guidelines berücksichtigen.

Gruß,
Dominik
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

dominik

Update auf v0.2 im 1. Post.

Es werden nun auch Events vom WebSocket (Port 8080) verarbeitet und in Readings hinterlegt. Aktuell noch nicht für alle Events implementiert. Zukünftig soll es dadurch möglich sein die Preset Tasten auch für andere Funktionen zu nutzen :)
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

Sonic

Hallo Dominik,

das ist Super. Ich freue mich sehr dass du das Thema Bose aufgreifst.
Ich teste dein Modul diese Tage
:) :)

gruss
KLAUS

Pythonf

Bei mir funktioniert es super. Wäre es möglich, den Powerbefehl durch set $Dev on bzw off ersetzen, sodass z.B. die Verwendung von Homekit kompatibel ist.
Eventuell mit Reading state on/off - falls es möglich ist, die Informationen zu erhalten?

Beste Grüße
Fabian

dominik

Zitat von: Pythonf am 16 Januar 2016, 12:18:53
Bei mir funktioniert es super. Wäre es möglich, den Powerbefehl durch set $Dev on bzw off ersetzen, sodass z.B. die Verwendung von Homekit kompatibel ist.
Eventuell mit Reading state on/off - falls es möglich ist, die Informationen zu erhalten?

Beste Grüße
Fabian

Kommt noch, wird dann anhand des Websockets (message source = STANDBY) ausgewertet. Damit werde ich on/off implementieren um das power toggle zu umgehen.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

purist

Hallo,

ich bin neu hier, lese aber schon einige Zeit manche Themen mit und habe als Programmier-Laie allerhöchsten Respekt vor den Machern hier. Danke!

Vielleicht ist die Frage blöd, aber: wie kann ich das Modul downloaden?

Danke,

purist

Pythonf

Du lädst die *.pm aus dem ersten Thread und kopierst sie in das Verzeichnis /fhem/FHEM . Dort sollten auch einige andere *.pm Dateien sein. Dann machst du in FHEM einen shutdown restart und definierst wie oben beschrieben

purist

Oh mann, ich glaub ich brauch ne Brille. Ich habe die .pm nicht gesehen :-) Also doch dumme Frage....

Danke jedenfalls!

VG purist

purist

Klappt Super, danke Dominik!

VG Purist

dominik

Neue Version im 1. Post.

ACHTUNG: Define wurde geändert, da jetzt alle Player per Autodiscover gefunden werden :)

v0.9
  - autodiscover BOSE SoundTouch players: autocreate BOSE_<deviceID>
  - add alias for newly created devices
  - update IP if the player IP changes
  - automatically re-connect websocket
  - support UTF-8 names with umlauts
  - reconnect websocket when connection closed
  - add firmware version & IP readings
  - automatically update /info on IP update
  - state: offline,playing,stopped,paused,online (online means standby)
  - support on/off commands based on current state
  - add support more readings for now_playing
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

dominik

Update v0.9.1 im 1. Post

- bugfix for on/off support
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

Theo

#14
Hallo Dominik,

zunächst: Vielen Dank für dieses Modul!

Die erste Installation ist bei mir die v0.9.1 (20160122), ich nutze einen Banana PI, Debian/Jessie, FHEM Dev. - Zweig (stets aktuell gehalten), eine neue Soundtouch 10 (via WiFi) und eine neue Soundtouch 20 (kabelgebunden).

Bei meiner Installation fehlte noch dieses Paket (mit den entsprechenden Abhängigkeiten):
apt-get install libnet-bonjour-perl

Die beiden Soundtouch werden problemlos erkannt, auch die Namen werden übernommen.

Im Logfile gibt es nach erfolgreicher Erkennung diese Fehlermeldung dieses Warning:
PERL WARNING: Thread 3 terminated abnormally: Undefined subroutine &main::usleep called at ./FHEM/98_BOSEST.pm line 538.

Bisher festgestellte Herausforderungen:
1.) on/off funktioniert nicht (auch kein Log - Eintrag)
Nach ,,shutdown restart" funktioniert ,,off", allerdings kein ,,on" möglich (auch kein Log - Eintrag)
2.) im Prinzip sind alle set - Anweisungen betroffen, Beispiel: volume - Anzeige falsch, ein paar mal verändert, mal geht nichts, mal wird ein Wert angenommen (dann ist die Anzeige auch korrekt), aktuell nur an der Wifi - ST 10 getestet, liegt vermutlich nicht an der Wifi - Verbindung an sich, Telnet auf die Box funktioniert ohne Einschränkung

Jede Änderung wurde vorher gespeichert, auch bereits mehrfach "shutdown restart" durchgeführt. Könnte dieses merkwürdige Verhalten mit der Log-Fehlermeldung bei der Erkennung zusammenhängen?

Viele Grüße
Theo