├── README.md
├── VERSION
├── ccu1
├── newudp
└── update_addon
├── ccu2
├── newudp
└── update_addon
├── ccu3
├── newudp
└── update_addon
├── ccu3x86
├── newudp
└── update_addon
├── generate_img.sh
├── rc.d
└── sonos2
├── sonos2
├── common.tcl
├── sonos2.tcl
├── sonos2_addon.cfg
└── stop.tcl
├── src
└── newudp
│ ├── Makefile
│ └── newudp.c
├── update_script
└── www
├── ZoneGroupState.txt
├── index.html
├── phpinc.php
├── public
├── css
│ ├── bootstrap-theme.min.css
│ ├── bootstrap.min.css
│ ├── bootstrapValidator.min.css
│ ├── custom.css
│ └── custombootstrap.css
├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ └── glyphicons-halflings-regular.woff
├── img
│ ├── Preloader.gif
│ ├── Preloader1.gif
│ ├── logo.png
│ ├── pause.png
│ ├── play.png
│ └── stop.png
└── js
│ ├── bootstrap.min.js
│ └── bootstrapValidator.min.js
├── server.cgi
├── settings
├── ZoneGroupState.txt
├── settings.cgi
├── settings.html
├── udp.cgi
└── udp.html
├── sonos2.cgi
├── sonos2inc.tcl
├── status.cgi
├── status.html
└── update-check.cgi
/README.md:
--------------------------------------------------------------------------------
1 | # HomeMatic Sonos Player Addon
2 | This repository hosts the development on a HomeMatic CCU-Addon for enabling a CCU to control Sono type audio players (www.sonos.com) from within the WebUI user interface.
3 |
4 | ## Supported CCU models
5 | * [HomeMatic CCU3](https://www.eq-3.de/produkte/homematic/zentralen-und-gateways/smart-home-zentrale-ccu3.html) / [RaspberryMatic](http://raspberrymatic.de/)
6 | * [HomeMatic CCU2](https://www.eq-3.de/produkt-detail-zentralen-und-gateways/items/homematic-zentrale-ccu-2.html)
7 | * HomeMatic CCU1
8 |
9 | ## Installation
10 | 1. Download the latest Addon release (https://github.com/homematic-community/hm-sonos/releases)
11 | 2. Upload it via the HomeMatic WebUI provided Addon functionality.
12 | 3. Login to your CCU and configure the Sonos Player Addon accordingly.
13 |
14 | ## Support
15 | If you encounter any problems or have any idea for enhancements of this addon please create a corresponding ticket at the issue tracker (https://github.com/homematic-community/hm-sonos/issues). For getting direct help a german speaking discussion fora is hosting a seperate discussion thread as well: http://homematic-forum.de/forum/viewtopic.php?f=41&t=26531
16 |
17 | ## License
18 | The Sonos CCU Addon as published in this Github repository is provided under the GPL license.
19 |
20 | ## Authors
21 | * The main developer of the addon is 'fiveyears' with the build environment and ports to the CCU1 and RaspberryMatic platform being performed by Jens Maus.
22 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 2.9
2 |
--------------------------------------------------------------------------------
/ccu1/newudp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu1/newudp
--------------------------------------------------------------------------------
/ccu1/update_addon:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu1/update_addon
--------------------------------------------------------------------------------
/ccu2/newudp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu2/newudp
--------------------------------------------------------------------------------
/ccu2/update_addon:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu2/update_addon
--------------------------------------------------------------------------------
/ccu3/newudp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu3/newudp
--------------------------------------------------------------------------------
/ccu3/update_addon:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu3/update_addon
--------------------------------------------------------------------------------
/ccu3x86/newudp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu3x86/newudp
--------------------------------------------------------------------------------
/ccu3x86/update_addon:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/ccu3x86/update_addon
--------------------------------------------------------------------------------
/generate_img.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | tar=$(which gtar) # OSX gnu tar
3 | if [ -z $tar ]; then
4 | tar="tar"
5 | fi
6 | mkdir -p tmp
7 | cp -a sonos2 tmp/
8 | cp -a rc.d tmp/
9 | cp -a www tmp/
10 | cp -a ccu1 tmp/
11 | cp -a ccu2 tmp/
12 | cp -a ccu3 tmp/
13 | cp -a ccu3x86 tmp/
14 | cp -a update_script tmp/
15 | cp -a VERSION tmp/sonos2/
16 | cd tmp
17 |
18 | $tar --owner=root --group=root --exclude=.DS_Store -czvf ../sonos2-addon-$(cat ../VERSION).tar.gz *
19 | cd ..
20 | rm -rf tmp
21 |
--------------------------------------------------------------------------------
/rc.d/sonos2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ADDONNAME=sonos2
4 | RCDDIR=/usr/local/etc/config/rc.d
5 | ADDONDIR=/usr/local/etc/config/addons/${ADDONNAME}
6 | WWWDIR=/usr/local/etc/config/addons/www/${ADDONNAME}
7 |
8 | AUTOSTART_SCRIPT=${ADDONNAME}
9 | START_SCRIPT=${ADDONNAME}.tcl
10 | STOP_SCRIPT=stop.tcl
11 | CONFIG_URL=/addons/${ADDONNAME}/settings/settings.cgi
12 |
13 | # check for unsupported platforms
14 | if grep -qim1 busmatic /www/api/methods/ccu/downloadFirmware.tcl; then
15 | exit 13
16 | fi
17 |
18 | # change to addon directory
19 | cd ${ADDONDIR}
20 |
21 | case "$1" in
22 | ""|start)
23 | tclsh $START_SCRIPT &
24 | ;;
25 |
26 | info)
27 | VER=$(cat ${ADDONDIR}/VERSION)
28 | echo "Version: ${VER}"
29 | echo "Info: Sonos Player CCU Addon
"
30 | echo "Info: Copyright (c) 2014-2021 fiveyears, Jens Maus
"
31 | echo "Info: https://github.com/homematic-community/hm-sonos"
32 | echo "Name: Sonos Player"
33 | echo "Operations: uninstall restart"
34 | echo "Config-Url: $CONFIG_URL"
35 | echo "Update: /addons/${ADDONNAME}/update-check.cgi"
36 | ;;
37 |
38 | restart)
39 | tclsh $STOP_SCRIPT
40 | tclsh $START_SCRIPT &
41 | ;;
42 |
43 | stop)
44 | tclsh $STOP_SCRIPT
45 | ;;
46 |
47 | uninstall)
48 | tclsh $STOP_SCRIPT
49 | cd ${RCDDIR}
50 |
51 | ${WWWDIR}/bin/update_addon ${ADDONNAME}
52 | rm -rf ${ADDONDIR}
53 | rm -rf ${WWWDIR}
54 | rm -rf ${AUTOSTART_SCRIPT}
55 | ;;
56 |
57 | *)
58 | echo "usage:"
59 | echo " ${ADDONNAME} [info|start|stop|restart|uninstall]"
60 | ;;
61 | esac
62 |
--------------------------------------------------------------------------------
/sonos2/common.tcl:
--------------------------------------------------------------------------------
1 | ##
2 | # common.tcl
3 | # Enthält gemeinsam verwendete Funktionen und Konstanten.
4 | #
5 | # @author F. Werner
6 | ##
7 |
8 | #*******************************************************************************
9 | # Allgemeine Konstanten
10 | #*******************************************************************************
11 |
12 | ##
13 | # Name des Addons.
14 | ##
15 | set ADDON_NAME "sonos2"
16 | #*******************************************************************************
17 | # Logmeldungen
18 | #*******************************************************************************
19 |
20 | ##
21 | # Loggt eine Nachricht.
22 | # @param message zu loggende Nachricht
23 | ##
24 | proc log { message } {
25 | global ADDON_NAME
26 |
27 | exec logger "$ADDON_NAME - $message"
28 | }
29 |
30 | #*******************************************************************************
31 | # Dateizugriff
32 | #*******************************************************************************
33 |
34 | ##
35 | # Speichert Daten in einer Datei.
36 | # @param fileName Name der Datei
37 | # @param Daten, die in die Datei geschrieben werden sollen
38 | ##
39 | proc saveToFile { fileName content } {
40 | set fd -1
41 |
42 | set fd [open $fileName w]
43 | if { $fd != -1 } then {
44 | puts -nonewline $fd $content
45 | close $fd
46 | } else {
47 | error "could not write file $fileName"
48 | }
49 | }
50 |
51 | ##
52 | # Liefert den Inhalt einer Datei.
53 | # @param fileName Name der Datei
54 | # @return Inhalt der Datei
55 | ##
56 | proc loadFromFile { fileName } {
57 | set fd -1
58 |
59 | set fd [open $fileName r]
60 | if { $fd != -1 } then {
61 | set result [read $fd]
62 | } else {
63 | error "could not read file $fileName"
64 | }
65 |
66 | return $result
67 | }
68 |
69 | #*******************************************************************************
70 | # PID-Datei
71 | #*******************************************************************************
72 |
73 | ##
74 | # Name der PID-Datei.
75 | ##
76 | set PID_FILE "$ADDON_NAME.pid"
77 |
78 | ##
79 | # Ermittelt, ob die Zusatzsoftware gerade läuft.
80 | # Es wird angenommen, dass die Zusatzsoftware läuft, solange die PID-Datei
81 | # existiert.
82 | # @return 1, falls die Zusatzsoftware gerade läuft
83 | ##
84 | proc isRunning { } {
85 | global PID_FILE
86 | return [file exists $PID_FILE]
87 | }
88 |
89 | ##
90 | # Schreibt die PID-Datei.
91 | # Die PID-Datei enthält die Prozess-Id der ausführenden Tcl-Instanz.
92 | ##
93 | proc writePidFile { } {
94 | global PID_FILE
95 |
96 | saveToFile $PID_FILE [pid]
97 | }
98 |
99 | ##
100 | # Liefert die PID aus der PID-Datei.
101 | # @return PID aus der PID-Datei
102 | ##
103 | proc readPidFile { } {
104 | global PID_FILE
105 |
106 | return [loadFromFile $PID_FILE]
107 | }
108 |
109 | ##
110 | # Löscht die PID-Datei
111 | ##
112 | proc removePidFile { } {
113 | global PID_FILE
114 |
115 | file delete $PID_FILE
116 | }
117 |
118 |
--------------------------------------------------------------------------------
/sonos2/sonos2.tcl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/homematic-community/hm-sonos/ce1d6d7a240feb38e9015364def159e1da747e80/sonos2/sonos2.tcl
--------------------------------------------------------------------------------
/sonos2/sonos2_addon.cfg:
--------------------------------------------------------------------------------
1 | {
2 | CONFIG_URL /addons/sonos2/settings/settings.cgi
3 | CONFIG_DESCRIPTION {
4 | de {
Die Sonoszonen müssen mindestens 20 Zeichen lang sein
" 87 | } 88 | } else { 89 | set helpSonoszone "Die Sonoszonen müssen eingegeben werden
" 90 | } 91 | if {$radio != ""} { 92 | if { [string length $radio] < 5 } { 93 | set helpRadio "Die Radioliste sollte mindestens 5 Zeichen lang sein
" 94 | } 95 | } 96 | if {$messagespeicher == ""} { 97 | set helpMessagespeicher "Der Messagepfad muss eingegeben werden
" 98 | } 99 | if {$stdvolume != ""} { 100 | if [string is integer $stdvolume] { 101 | set stdvolume [ expr round($stdvolume) ] 102 | if { $stdvolume > 100 || $stdvolume < 0 } { 103 | set helpStdvolume "Das Standard-Volume muss zwischen 0 und 100 sein
" 104 | } 105 | } else { 106 | set helpStdvolume "Das Standard-Volume muss eine ganze Zahl sein
" 107 | } 108 | } else { 109 | set helpStdvolume "Das Standard-Volume muss eingegeben werden
" 110 | } 111 | if {$timeout != ""} { 112 | if [string is integer $timeout] { 113 | set timeout [ expr round($timeout) ] 114 | if { $timeout > 10 || $timeout < 1 } { 115 | set helpTimeout "Das Timeout muss zwischen 1 und 10 sein
" 116 | } 117 | } else { 118 | set helpTimeout "Das Timeout muss eine ganze Zahl sein
" 119 | } 120 | } else { 121 | set helpTimeout "Das Timeout muss eingegeben werden
" 122 | } 123 | if {$volumeup != ""} { 124 | if [string is integer $volumeup] { 125 | set volumeup [ expr round($volumeup) ] 126 | if { $volumeup > 20 || $volumeup < 1 } { 127 | set helpVolumeup "Das VolumeUp muss zwischen 1 und 20 sein
" 128 | } 129 | } else { 130 | set helpVolumeup "Das VolumeUp muss eine ganze Zahl sein
" 131 | } 132 | } else { 133 | set helpVolumeup "Das VolumeUp muss eingegeben werden
" 134 | } 135 | if {$volumedown != ""} { 136 | if [string is integer $volumedown] { 137 | set volumedown [ expr round($volumedown) ] 138 | if { $volumedown > 20 || $volumedown < 1 } { 139 | set helpVolumedown "Das VolumeDown muss zwischen 1 und 20 sein
" 140 | } 141 | } else { 142 | set helpVolumedown "Das VolumeDown muss eine ganze Zahl sein
" 143 | } 144 | } else { 145 | set helpVolumedown "Das VolumeDown muss eingegeben werden
" 146 | } 147 | if {$messagevolume != ""} { 148 | if [string is integer $messagevolume] { 149 | set messagevolume [ expr round($messagevolume) ] 150 | if { $messagevolume > 100 || $messagevolume < 0 } { 151 | set helpMessagevolume "Das Message-Volume muss zwischen 0 und 100 sein
" 152 | } 153 | } else { 154 | set helpMessagevolume "Das Message-Volume muss eine ganze Zahl sein
" 155 | } 156 | } else { 157 | set helpMessagevolume "Das Message-Volume muss eingegeben werden
" 158 | } 159 | if { "$helpMessagevolume$helpVolumedown$helpVolumeup$helpStdvolume$helpMessagespeicher$helpSonoszone$helpRadio$helpTimeout" != ""} { 160 | set message "$message [getMessage "Die Daten konnten wegen Eingabefehlern nicht gespeichert werden!" danger]" 161 | 162 | } else { 163 | set message "$message [getMessage "Daten gespeichert" success]" 164 | set Cfg::stdvolume $stdvolume 165 | set Cfg::volumeup $volumeup 166 | set Cfg::volumedown $volumedown 167 | set Cfg::messagevolume $messagevolume 168 | set Cfg::messagespeicher $messagespeicher 169 | set Cfg::timeout $timeout 170 | if { $::tcl_version != "8.2" } { 171 | set Cfg::sonoszone [regexp -all -inline {\S+} $sonoszone] 172 | } else { 173 | regsub -all {\s+} $sonoszone " " Cfg::sonoszone ;# whitespace zu Space 174 | } 175 | regsub -all "\r" $radio {} radio 176 | set radio [split $radio "\n"] 177 | set Cfg::radio {} 178 | foreach line $radio { 179 | set line [string trim $line] 180 | set sid [lindex $line 0] 181 | set station [string trim [join [lreplace $line 0 0 {}]]] 182 | lappend Cfg::radio $sid $station 183 | } 184 | Cfg::Save 185 | set button "reload" 186 | } 187 | } 188 | } else { 189 | set button "reload" 190 | } 191 | if {$button == "reload"} { 192 | Cfg::Load 193 | set radio "" 194 | regsub -all {(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s+} $Cfg::sonoszone "\\1\n" sonoszone ;#" %> 195 | foreach {sid station} $Cfg::radio { 196 | set radio "$radio\n$sid $station" 197 | } 198 | set timeout $Cfg::timeout 199 | set stdvolume $Cfg::stdvolume 200 | set volumeup $Cfg::volumeup 201 | set volumedown $Cfg::volumedown 202 | set messagevolume $Cfg::messagevolume 203 | set messagespeicher $Cfg::messagespeicher 204 | } 205 | set content [loadFile settings.html] 206 | set zone "" 207 | parseQuery 208 | if [info exists args(zone)] { 209 | if {$args(zone) != "" && $args(zone) != "fehlt"} { set zone "?zone=$args(zone)"} 210 | } 211 | regsub -all {<%zone%>} $content $zone content ;#" %> 212 | regsub -all {<%message%>} $content $message content ;#" %> 213 | regsub -all {<%sonoszone%>} $content "$sonoszone" content ;#" %> 214 | regsub -all {<%stdvolume%>} $content $stdvolume content ;#" %> 215 | regsub -all {<%volumeup%>} $content $volumeup content ;#" %> 216 | regsub -all {<%volumedown%>} $content $volumedown content ;#" %> 217 | regsub -all {<%messagevolume%>} $content $messagevolume content ;#" %> 218 | regsub -all {<%messagespeicher%>} $content $messagespeicher content ;#" %> 219 | regsub -all {<%timeout%>} $content $timeout content ;#" %> 220 | regsub -all {<%radio%>} $content $radio content ;#" %> 221 | regsub -all {<%helpSonoszone%>} $content "$helpSonoszone" content ;#" %> 222 | regsub -all {<%helpStdvolume%>} $content $helpStdvolume content ;#" %> 223 | regsub -all {<%helpVolumeup%>} $content $helpVolumeup content ;#" %> 224 | regsub -all {<%helpVolumedown%>} $content $helpVolumedown content ;#" %> 225 | regsub -all {<%helpMessagevolume%>} $content $helpMessagevolume content ;#" %> 226 | regsub -all {<%helpMessagespeicher%>} $content $helpMessagespeicher content ;#" %> 227 | regsub -all {<%helpTimeout%>} $content $helpTimeout content ;#" %> 228 | regsub -all {<%helpRadio%>} $content $helpRadio content ;#" %> 229 | 230 | puts "Content-type:text/html\n" 231 | puts $content 232 | -------------------------------------------------------------------------------- /www/settings/settings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |