NEWS
Sprachansage über squeezebox
-
Hallo allerseits,
Ich möchte Ansagen einerseits über sayit (was funktioniert) und andererseits über die squeezebox (was auch funktioniert) realisieren.
Wobei ich jetzt ein Problem habe ist, dass bei der Ansage über die squeezebox nicht jedes mal das gleiche Ergebnis erzielt wird. Die Squeezboxclients laufen auf Raspberries, alle spielen brav die Musik und lassen sich auch toll über den Squeezboxadapter bedienen, wenn ich allerdings ein MP3-File über alle ausgeben will, machen oft nicht alle mit. Witzigerweise immer unterschiedliche.
Ich denke meine Scripte hauen nicht ganz hin und da ich vom Profiprogrammierer weit entfernt bin, würde ich Euch bitten, die Scripte einmal durchzusehen.
zb. für die Glocke, ich verwende zwei Scripte, eines für die Glocke selber, welche dann die URL an das zweite Script "Ansage" übergibt. Ich übergebe auch das "Ausgabemedium Squeezebox" da ich über dieses Script zukünftig die sayit Ansagen laufen lassen möchte. Über Glocke lasse ich mir auch Bilder einer IP-Cam senden:
Glocke:
function sendImage() { var request = require('request'); var fs = require('fs'); request.get({url: 'http://192.168.1.100/GetImage.cgi?account=admin&password=badger01', encoding: 'binary'}, function (err, response, body) { fs.writeFile("/tmp/snap.jpg", body, 'binary', function(err) { if (err) { console.error(err); } else { console.log('Snapshot sent'); sendTo('telegram.0', '/tmp/snap.jpg'); } }); }); } on({id: "hm-rpc.0.MEQ0655551.1.PRESS_SHORT"/*Klingelsensor.PRESS_SHORT*/, change: "any"}, function (dp) { //var test = getState("hm-rpc.0.MEQ0655551.1.PRESS_SHORT"/*Klingelsensor.PRESS_SHORT*/); if (dp.state.val) { //if(martin_bett.val) setState("sayit.0.tts.text"/*Text to speech*/, "Es hat geläutet!"); // send 4 images: immediately, in 5, 15 and 30 seconds sendImage(); setTimeout(sendImage, 5000); setTimeout(sendImage, 15000); setTimeout(sendImage, 30000); ansage("http://192.168.1.10:9002/status.html?p0=playlist&p1=play&p2=/home/data/eigene_dateien/gemeinsames/Reihenhaus/Homematic/Sprachfiles/gelaeutet.mp3", "squeezebox", "6000"); //setState("sayit.0.tts.text"/*Text to speech*/, "Ding Dong"); } });
Ansage:
function ansage(text, system, laenge) { // Sprachlautstärke an Tagwache.alle anpassen var martin = getState("hm-rega.0.4568"/*Tagwache_Martin*/); var babsi = getState("hm-rega.0.62463"/*Tagwache_Babsi*/); var alex = getState("hm-rega.0.63291"/*Tagwache_Alexander*/); if(martin.val && babsi.val && alex.val) sprach_vol = 75;//85 else sprach_vol = 55; // schauen ob der Radio schon eingeschaltet ist var power_bad = getState("squeezebox.0.Badezimmer.power"/*Badezimmer.power*/); var power_dbr = getState("squeezebox.0.Dachbodenraum.power"/*Dachbodenraum.power*/); var power_keller = getState("squeezebox.0.Keller.power"/*Keller.power*/); var power_kueche = getState("squeezebox.0.Küche.power"/*Küche.power*/); var power_wc = getState("squeezebox.0.WC-oben.power"/*WC-oben.power*/); // die aktuelle Lautstärke zwischenspeichern var volume_bad = getState("squeezebox.0.Badezimmer.volume"/*Badezimmer.volume*/); var volume_dbr = getState("squeezebox.0.Dachbodenraum.volume"/*Dachbodenraum.volume*/); var volume_keller = getState("squeezebox.0.Keller.volume"/*Keller.volume*/); var volume_kueche = getState("squeezebox.0.Küche.volume"/*Küche.volume*/); var volume_wc = getState("squeezebox.0.WC-oben.volume"/*WC-oben.volume*/); //schauen ob die Ausgabe über Squeezebox geht if(system == "squeezebox") { //alle Radios einschalten if(power_bad.val === false) setState("squeezebox.0.Badezimmer.power"/*Badezimmer.power*/, true); if(power_dbr.val === false) setTimeout(function() {setState("squeezebox.0.Dachbodenraum.power"/*Dachbodenraum.power*/, true);}, 10); if(power_keller.val === false) setTimeout(function() {setState("squeezebox.0.Keller.power"/*Keller.power*/, true);}, 20); if(power_kueche.val === false) setTimeout(function() {setState("squeezebox.0.Küche.power"/*Küche.power*/, true);}, 30); if(power_wc.val === false) setTimeout(function() {setState("squeezebox.0.WC-oben.power"/*WC-oben.power*/, true);}, 40); setTimeout(function() {setState("squeezebox.0.Badezimmer.volume"/*Badezimmer.volume*/, sprach_vol);}, 50); setTimeout(function() {setState("squeezebox.0.Dachbodenraum.volume"/*Dachbodenraum.volume*/, sprach_vol);}, 60); setTimeout(function() {setState("squeezebox.0.Keller.volume"/*Keller.volume*/, sprach_vol);}, 70); setTimeout(function() {setState("squeezebox.0.Küche.volume"/*Küche.volume*/, sprach_vol);}, 80); setTimeout(function() {setState("squeezebox.0.WC-oben.volume"/*WC-oben.volume*/, sprach_vol);}, 90); //Ausgabe des files über squeezebox setTimeout(function(){request = require('request')(text);}, 200); //Radios die aus waren, wieder ausschalten if(power_bad.val === false) setTimeout(function() {setState("squeezebox.0.Badezimmer.power"/*Badezimmer.power*/, false);}, 6120); if(power_dbr.val === false) setTimeout(function() {setState("squeezebox.0.Dachbodenraum.power"/*Dachbodenraum.power*/, false);}, 6120); if(power_keller.val === false) setTimeout(function() {setState("squeezebox.0.Keller.power"/*Keller.power*/, false);}, 6130); if(power_kueche.val === false) setTimeout(function() {setState("squeezebox.0.Küche.power"/*Küche.power*/, false);}, 6140); if(power_wc.val === false) setTimeout(function() {setState("squeezebox.0.WC-oben.power"/*WC-oben.power*/, false);}, 6150); //Lautstärke wieder auf den Ursprung zurücksetzen setTimeout(function() {setState("squeezebox.0.Badezimmer.volume"/*Badezimmer.volume*/, volume_bad.val);}, 6160); setTimeout(function() {setState("squeezebox.0.Dachbodenraum.volume"/*Dachbodenraum.volume*/, volume_dbr.val);}, 6170); setTimeout(function() {setState("squeezebox.0.Keller.volume"/*Keller.volume*/, volume_keller.val);}, 6180); setTimeout(function() {setState("squeezebox.0.Küche.volume"/*Küche.volume*/, volume_kueche.val);}, 6190); setTimeout(function() {setState("squeezebox.0.WC-oben.volume"/*WC-oben.volume*/, volume_wc.val);}, 6200); //Radio wieder starten setTimeout(function() {require('request') ("http://192.168.1.10:9002/status.html?p0=playlist&p1=play&p2=Radio%20Wien&player=b8:27:eb:79:b1:36");}, 6210); } }
Besten Dank im Voraus
Martin
-
Hallo Martin,
mir kam die Nutzung von require ungewohnt vor. Probier mal meine Variante.
Ebenso habe ich das Skript etwas verkürzt und statt setTimeout in Verbindung mit setState zu nutzen, bietet sich setStateDelayed an.
Die Verzögerungen unterscheiden sich ja zum Teil nur um Hundertstel Sekunden. Ich bin nicht sicher, ob das nicht etwas zu klein aufgelöst ist. Der HM-RPC-Adapter sorgt schon selbst dafür, dass nicht zuviel Funkverkehr gleichzeitig entsteht,
! ````
function ansage(text, system, laenge) {
var request = require('request');// Sprachlautstärke an Tagwache.alle anpassen var martin = getState("hm-rega.0.4568" /*Tagwache_Martin*/ ).val; var babsi = getState("hm-rega.0.62463" /*Tagwache_Babsi*/ ).val; var alex = getState("hm-rega.0.63291" /*Tagwache_Alexander*/ ).val; if (martin && babsi && alex) sprach_vol = 75; //85 else sprach_vol = 55;
! // schauen ob der Radio schon eingeschaltet ist
var power_bad = getState("squeezebox.0.Badezimmer.power" /Badezimmer.power/ ).val;
var power_dbr = getState("squeezebox.0.Dachbodenraum.power" /Dachbodenraum.power/ ).val;
var power_keller = getState("squeezebox.0.Keller.power" /Keller.power/ ).val;
var power_kueche = getState("squeezebox.0.Küche.power" /Küche.power/ );
var power_wc = getState("squeezebox.0.WC-oben.power" /WC-oben.power/ ).val;
! // die aktuelle Lautstärke zwischenspeichern
var volume_bad = getState("squeezebox.0.Badezimmer.volume" /Badezimmer.volume/ ).val;
var volume_dbr = getState("squeezebox.0.Dachbodenraum.volume" /Dachbodenraum.volume/ ).val;
var volume_keller = getState("squeezebox.0.Keller.volume" /Keller.volume/ ).val;
var volume_kueche = getState("squeezebox.0.Küche.volume" /Küche.volume/ ).val;
var volume_wc = getState("squeezebox.0.WC-oben.volume" /WC-oben.volume/ ).val;
! //schauen ob die Ausgabe über Squeezebox geht
if (system == "squeezebox") {
//alle Radios einschalten
if (!power_bad) setState("squeezebox.0.Badezimmer.power" /Badezimmer.power/ , true);
if (!power_dbr) setStateDelayed("squeezebox.0.Dachbodenraum.power" /Dachbodenraum.power/ , true, 10);
if (!power_keller) setStateDelayed("squeezebox.0.Keller.power" /Keller.power/ , true, 20);
if (!power_kueche) setStateDelayed("squeezebox.0.Küche.power" /Küche.power/ , true, 30);
if (!power_wc) setStateDelayed("squeezebox.0.WC-oben.power" /WC-oben.power/ , true, 40);
setStateDelayed("squeezebox.0.Badezimmer.volume" /Badezimmer.volume/ , sprach_vol, 50);
setStateDelayed("squeezebox.0.Dachbodenraum.volume" /Dachbodenraum.volume/ , sprach_vol, 60);
setStateDelayed("squeezebox.0.Keller.volume" /Keller.volume/ , sprach_vol, 70);
setStateDelayed("squeezebox.0.Küche.volume" /Küche.volume/ , sprach_vol, 80);
setStateDelayed("squeezebox.0.WC-oben.volume" /WC-oben.volume/ , sprach_vol, 90);//Ausgabe des files über squeezebox setTimeout(function() { request(text); }, 200);
! //Radios die aus waren, wieder ausschalten
if (!power_bad) setStateDelayed("squeezebox.0.Badezimmer.power" /Badezimmer.power/ , false, 6110);
if (!power_dbr) setStateDelayed("squeezebox.0.Dachbodenraum.power" /Dachbodenraum.power/ , false, 6120);
if (!power_keller) setStateDelayed("squeezebox.0.Keller.power" /Keller.power/ , false, 6130);
if (!power_kueche) setStateDelayed("squeezebox.0.Küche.power" /Küche.power/ , false, 6140);
if (!power_wc) setStateDelayed("squeezebox.0.WC-oben.power" /WC-oben.power/ , false, 6150);//Lautstärke wieder auf den Ursprung zurücksetzen setStateDelayed("squeezebox.0.Badezimmer.volume" /*Badezimmer.volume*/ , volume_bad, 6160); setStateDelayed("squeezebox.0.Dachbodenraum.volume" /*Dachbodenraum.volume*/ , volume_dbr, 6170); setStateDelayed("squeezebox.0.Keller.volume" /*Keller.volume*/ , volume_keller, 6180); setStateDelayed("squeezebox.0.Küche.volume" /*Küche.volume*/ , volume_kueche, 6190); setStateDelayed("squeezebox.0.WC-oben.volume" /*WC-oben.volume*/ , volume_wc, 6200); //Radio wieder starten setTimeout(function() { request("http://192.168.1.10:9002/status.html?p0=playlist&p1=play&p2=Radio%20Wien&player=b8:27:eb:79:b1:36"); }, 6210); }
}
Gruß Pix
-
Ich glaube es hat was mit Timing zu tun.
Erst mal die Timeouts unter 20ms können gar nicht eingehalten werden.
PC z.B kann nur 12-16ms, falls IDLE und konnte viel länger sein, falls was zu tun ist.
D.h. es kann gut sein, dass Volume bei einem nicht laufenden Radio eingestellt wird.
Ich wurde die Timeouts um Faktor 10 erhöhen, 100, 200, 300, … 900
Und dann text erst nach 1500ms ausgeben.
-
ok, danke Jungs, werde ich bisschen später probieren
-
Ich würde gerne genauso Sayit mit Squeezbox kombinieren. Bin aber leider in JS nicht so fit, und verwende Blocky. Wie kann ich die Squeezboxanbindung in Blocky realisieren?
-
Das würde mich auch mal interessieren wie das funktioniert.
Ich habe das Squeezebox Radio Teil. In der Vergangenheit hatte ich mal ein bischen mit dem squeezebox-Adapter rumgespielt ohne was Sinnvolles hinzubekommen.
-
Das würde mich auch mal interessieren wie das funktioniert.
Ich habe das Squeezebox Radio Teil. In der Vergangenheit hatte ich mal ein bischen mit dem squeezebox-Adapter rumgespielt ohne was Sinnvolles hinzubekommen. `
So. Bin schon einen Schritt weiter. Basics sind gelegt, mit dem Script nehme ich als nächstes in Angriff. Hier mal eine Erklärung wie es (einfach) funktionieren kann:Konstellation: Squeezebox Server auf Synology, zwei Clients zum Abspielen in Form eines Squeezebox Radio und ein Raspberry Pi1 (Lautsprecher an 3,5mm) mit PiCorePlayer:
- für Synology im Paket Zentrum Logitech Media Server installieren.
2a) Squeezebox Radio mit Logitech Media Server verbinden.
2b) Auf Raspberry PiCorePlayer installieren und starten (https://sites.google.com/site/picorepla … e/download)
-
Squeezebox Adapter in ioBroker installieren. Port ist standardmäßig 9090.
-
dann sollten die Objekte angelegt werden:
-
sollte es nicht funktionieren kann man den Server aufrufen unter IP_Logitech-Server:9002 und sehen ob die Player oben rechts auswählbar sind:
Das ganze lief bei mir ohne Probleme und es fällt auf, dass die Kommandos an die Geräte verzögerungsfrei weitergegebn werden. Die Musik startet sofort!
-
Ich werde mich bald auch mal mit den Sprachdurchsagen auf der Squeezebox beschäftigen. Bisher hab ich die vom Home Assistant steuern lassen. Da gab es auch ein kleines Programm dass die aktuellen Zustände des Players (Playlist, Lautstärke, etc) in einem file gespeichert hat, damit sie nach der Durchsage wieder hergestellt werden können.
Vielleicht kann das jemand gebrauchen:
by smazman https://community.home-assistant.io/t/squeezebox-audio-alert-script/11774
squeezebox_alert_save_playlist.sh
! ````
! #!/bin/bash
! #squeezebox_alert_save_playlist.sh
! #NOTE: Edit "user", "pass", ip and port below
JSONRPC="http://user:pass@192.168.1.100:9000/jsonrpc.js"
! #Example command arguments
#playlist_name="bedroom"
#mac="00:04:20:01:02:03"
#alert_volume=60
! playlist_name=$1
mac=$2
alert_volume=$3
! #get power state
power=$(curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["power","?"]]}'
$JSONRPC | jq '.result._power')
! prev_power=0
if [[ $power =~ .1. ]] ; then
prev_power=1
fi
echo "prev_power=$prev_power"
! #get play mode
mode=$(curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mode","?"]]}'
$JSONRPC | jq '.result._mode')
! prev_playmode=0
if [[ $mode =~ .play. ]] ; then
prev_playmode=1
fi
echo "prev_playmode=$prev_playmode"
! noplay=1
prev_time=0
if [ $prev_playmode -eq 1 ] ; then
noplay=0pause currently playing song
curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["pause"]]}' $JSONRPC
echo "pause currently playing song"! # get paused time
prev_time=$(curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["time","?"]]}'
$JSONRPC | jq '.result._time')
echo "prev_time=$prev_time"
fi
! # save current playlist
curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","save","'"$playlist_name"'","silent:1"]]}' $JSONRPC
echo "save current playlist"
! # GET SETTINGS TO RESTORE AFTER PLAYING ALERT SONG
#get current volume
prev_volume=$(curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume","?"]]}'
$JSONRPC | jq '.result._volume')
echo "prev_volume=$prev_volume"
! #get current repeat setting
prev_repeat=$(curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat","?"]]}'
$JSONRPC | jq '.result._repeat')
echo "prev_repeat=$prev_repeat"
! #write settings to file
DIRECTORY=$(cddirname $0
&& pwd)
echo "Save settings to file: $DIRECTORY/$playlist_name.txt"
"$DIRECTORY/$playlist_name.txt"
printf '%s\n%s\n%s\n%s\n%s\n' $prev_power $prev_playmode $prev_time $prev_volume $prev_repeat > "$DIRECTORY//$playlist_name.txt"
! # SET SETTINGS FOR ALERT SONG
#set alert_volume to command argument value
curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume",'$alert_volume']]}' $JSONRPC
echo "set alert_volume"
! #set repeat setting to 0
curl -X GET -H "Content-Type: application/json"
-d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat",0]]}' $JSONRPC
echo "set repeat_setting to 0"squeezebox_alert_restore_playlist.sh >! ```` #!/bin/bash >! #squeezebox_alert_restore_playlist.sh >! #NOTE: Edit "user", "pass", ip and port below JSONRPC="http://user:pass@192.168.1.100:9000/jsonrpc.js" >! #Example command arguments #playlist_name="bedroom" #mac="00:04:20:01:02:03" >! playlist_name=$1 mac=$2 >! # WAIT FOR ALERT SONG TO STOP PLAYING echo "wait for alert song to stop playing" cur_mode="play" while [[ $cur_mode =~ .*play.* ]]; do sleep 1 cur_mode=$(curl -X GET -H "Content-Type: application/json" \ -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mode","?"]]}' \ $JSONRPC | jq '.result._mode') done >! echo "alert song stopped playing" >! # read settings from file DIRECTORY=$(cd `dirname $0` && pwd) echo "Restore settings from file: $DIRECTORY/$playlist_name.txt" IFS=/r>\n' read -d '' -r -a lines < "$DIRECTORY/$playlist_name.txt" prev_power="${lines[0]}" prev_playmode="${lines[1]}" prev_time="${lines[2]}" prev_volume="${lines[3]}" prev_repeat="${lines[4]}" echo "prev_power=$prev_power" echo "prev_playmode=$prev_playmode" echo "prev_time=$prev_time" echo "prev_volume=$prev_volume" echo "prev_repeat=$prev_repeat" >! noplay=1 if [ $prev_playmode -eq 1 ] ; then noplay=0 fi >! # RESTORE PREVIOUS SETTINGS #restore prev_volume setting curl -X GET -H "Content-Type: application/json" \ -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["mixer","volume",'"$prev_volume"']]}' $JSONRPC echo "restore prev_volume setting" >! #restore prev_repeat setting curl -X GET -H "Content-Type: application/json" \ -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","repeat",'"$prev_repeat"']]}' $JSONRPC echo "restore prev_repeat setting" >! # resume previous playlist curl -X GET -H "Content-Type: application/json" \ -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["playlist","resume","'"$playlist_name"'","noplay:'$noplay'"]]}' $JSONRPC echo "resume previous playlist" >! # RESUME PREVIOUSLY PLAYING MUSIC if [ $prev_playmode -eq 1 ] ; then #skip ahead in song to prev_time curl -X GET -H "Content-Type: application/json" \ -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["time",'"$prev_time"']]}' $JSONRPC echo "skip ahead in song to prev_time" fi >! #restore prev_power setting if [ $prev_power -eq 0 ] ; then echo "prev_power setting was off, power off" curl -X GET -H "Content-Type: application/json" \ -d '{"id":1,"method":"slim.request","params":["'"$mac"'",["power",0]]}' $JSONRPC fi
Müsste ich doch eigentlich einfach über exec ausführen können, oder?
-
@rascal Kannst du bitte einmal deine aktuelle Version hier rein stellen? Leider sind bei den "Verbesserungen" von z.B. Pix der Code hier nicht mehr sauber kopierbar. Liegt bestimmt am Forumsumzug. Denke du hast mittlerweile genug Erfahrung gesammelt, sodass dein Skrip perfektioniert ist