more G-Labs products

Author Topic: Squeezebox on homegenie  (Read 10932 times)

February 03, 2015, 10:03:17 PM
Read 10932 times

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
Hello to all,
i would like to connect my home music entertainment with Home genie.
Squeezebox is a internet radio and can play music saved on a server ( I installed on raspberry).
This server give the possibility to pilot remotely the radio. Others Home automation systems (openhab) i see that they implemented. I would like to trigget my presence with a surrounded music and play alarm sound.

So... i would like to implement .

On the server there is a XML that give you the status of the radio and the links to pilot the radio (turn on, off, volume, play song, play radio... ). I attach the xml downloaded but i don t know how to parse this file on automation.

Can someone help to extract just one information from the file ( i will complete the interface ) and how to add a button and a text in a widget?

Thank you very much

This is my base :

The trigger code:
// this Setup delegate will be executed once, when program become active
Program.Setup(()=>
{
 
    // list the program as custom weather widget
    Program.AddControlWidget( "music/squeezebox/LMS" );
   
    // set input fields parameters
    // <field_name>, <default_value>, <description>
    Program.AddInputField("LMSServer", "192.168.192.19", "IP Address of Logitech Media Server");
    Program.AddInputField("LMSPort", "9000", "Port of the server");
    Program.AddInputField("MACPlayer", "00%3A04%3A20%3A29%3A62%3A10", "MacAddress of squeezebox player %3A for point");
   
 
    Program.Parameter("squeezebox.Song").Value = "";
   
});
//
return true;

And the program code

while (Program.IsEnabled)
{

    var LMSServer = Program.InputField("LMSServer").Value;
    var LMSPort = Program.InputField("LMSPort").Value;
    var MACPlayer = Program.InputField("MACPlayer").Value;
    //
    try
    {
        var serviceurl = "http://" + LMSServer + ":" + LMSPort + "/status.xml&player=" + MACPlayer;
        dynamic geodata = Net.WebService(serviceurl).GetData();
        //Program.Parameter("squeezebox.Song").Value = geodata.playingSong;
         Program.Notify("Squeeze box updated", "Updated.");
    }
    catch (Exception ex)
    {
     
         Program.Notify("Squeezebox Error!", "Unable to get data from service " + "http://" + LMSServer + ":" + LMSPort + "/status.xml&player=" + MACPlayer);
         Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
   
    }
    //
    Pause(10); // pause 24 hours before next check
}







 

February 09, 2015, 10:44:21 PM
Reply #1

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi,
I take a look at your file, which information did you need ?
did you try to use the HG function :
Code: [Select]
Net.WebService("<URL>").GetData()Documentation
http://www.homegenie.it/docs/doxy/d1/d60/class_home_genie_1_1_automation_1_1_scripting_1_1_net_helper.html#a08d047072bdd8bcefd1645de3dc6eda0
Example
http://freegeoip.net/json/
Bye

February 17, 2015, 06:24:11 AM
Reply #2

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi,
I try your script yesterday but the get on status always fail and go in exception part.
Is it ok for you ?
Last, I try to find a good documentation, about the API available, but I didn't find one. I found a lot of website with partial and not running on my side. Perhaps it depends of squeezebox server version.
Did you have one ?
Bye

February 17, 2015, 10:33:21 PM
Reply #3

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
thank you very much,

I found some documentation and there is a better way to integrate this on homegenie.
Logitech media server has a port 9090 ( called CLI - command line interface ) that you can speak biderectionaly TCP-IP with your squeezebox.

documentation is here:
https://crestron-squeeze.googlecode.com/files/cli-api_7.6.htm

This is the right and better way, because the media server can send feedbacks.

Then we need
1  help to create the connection to the 9090 port with tcp.
2 manage a little buffer on input string and a parser to manage events ( i can do )
3 send strings commands to the LMS

Nolio do you know how to open this stream on c sharp?

maybe there is some code reusable on others components?




 

February 17, 2015, 10:35:37 PM
Reply #4

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
Nolio sorry for your wasted time on XML  :-[ but there is a lot of interfaces to this media server

February 19, 2015, 06:46:58 AM
Reply #5

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
@igorrobertifoc I see the command line option too but (for me) it doesn't seem a good way ...
By the way, to use a tcp connexion, the documentation is here :
http://www.homegenie.it/docs/doxy/d9/d20/class_home_genie_1_1_automation_1_1_scripting_1_1_tcp_client_helper.html
and an example :
Code: [Select]
////////////////////// Send SMS //////////////////////
var remoteserversms = "xx.xx.xx.xx"; //@IP of your server with python script
TcpClient
   .Service( remoteserversms ) // server
   .Connect( xxxx ); // tcp port number
TcpClient.SendMessage("Test ..... ");
Pause(1);
TcpClient.Disconnect();
Pause(1);
////////////////////////////////////////////////////////////

February 22, 2015, 11:00:12 PM
Reply #6

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
i tryed with the sintax and IP of the LMS server but doesn t work. With putty on the same way it work. How I can debug? Here is my code:

Code: [Select]
  Action<string> HandleMessageReceived = (string message) => {
Program.Notify("Squeeze", message);
      };

       var remoteServer = "192.168.192.19";
       var remotePort = 9090;
   //var MACPlayer = "00:04:20:29:62:10";
     
        TcpClient.OnStringReceived( HandleMessageReceived );
       
TcpClient.EndOfLine = "\n";
TcpClient.Service( remoteServer );
        TcpClient.Connect( remotePort );
Pause(2);
        TcpClient.SendMessage("00:04:20:29:62:10 show line1:Hello%20World line2:Second%20line duration:1 centered:1<LF>");

  Program.Notify("Squeeze", "Squeeze2");

Pause(5);
TcpClient.Disconnect();
Pause(15);

February 23, 2015, 08:35:36 PM
Reply #7

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi igorrobertifoc,

I found the problem (thanks wireshark :)) by adding \n :
Code: [Select]
Action<string> HandleStringReceived = (string message) => {
Program.Notify("Squeeze", message);
};
var remoteServer = "x.x.x.x";
var remotePort = 9090;
TcpClient.OnStringReceived( HandleStringReceived );
TcpClient
  .Service( remoteServer )
.Connect( remotePort );
TcpClient.SendMessage("xx:xx:xx:xx:xx:xx title ?\n");
Pause(5);
TcpClient.SendMessage("exit\n");
Pause(1);
TcpClient.Disconnect();
Pause(5);

Bye
« Last Edit: February 24, 2015, 07:27:33 AM by nolio »

February 23, 2015, 08:48:20 PM
Reply #8

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
Great, it work with a \n at the end

February 23, 2015, 10:38:24 PM
Reply #9

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
Ok, it works. If i change volume or I turn off HomeGenie catch the events!I attach the code.
How I can set some action to the module (in a good way for Home Genie)?
I will use in a widget or in some scenes.. like:
squezebox.start()
squezebox.stop()
squezebox.streamRadio("http:// ......")
squezebox.playAlarm()   

alarm will be triggered from home genie alarm status



Code: [Select]
    var remoteServer = Program.InputField("LMSServer").Value;
    var remotePort = Program.InputField("LMSPort").Value;
    var MACPlayer = Program.InputField("MACPlayer").Value;
   
    Action<string> HandleMessageReceived = (string message) => {
      string[] msg = ((string)message).Split(' ');
            switch(msg[1])
              {
                case "power":
                if (string.Compare(Program.Parameter("squeezebox.power").Value,msg[2]) != 0) {
                    Program.Parameter("squeezebox.power").Value = msg[2];
                    Program.RaiseEvent( "squeezebox.power", msg[2], "Squeeze box Power");
                }
              break;
                case "mixer":
                if (string.Compare(Program.Parameter("squeezebox.volume").Value,msg[3]) != 0 && string.Compare(msg[2], "volume")==0) {
                    Program.Parameter("squeezebox.volume").Value = msg[3];
                    Program.RaiseEvent("squeezebox.volume", msg[3], "Squeeze box Volume");
                }
              break;
                case "title":
                if (string.Compare(Program.Parameter("squeezebox.title").Value,msg[2]) != 0 ) {
                    Program.Parameter("squeezebox.title").Value = msg[2];
                    Program.RaiseEvent( "squeezebox.title", msg[2], "Squeeze box Volume");
                }
              break;
              }

   
    };
        TcpClient.OnStringReceived( HandleMessageReceived ); 
TcpClient.EndOfLine = "\n";
TcpClient.Service( remoteServer );
        TcpClient.Connect( 9090 );
TcpClient.SendMessage(MACPlayer + " power ?\n");
TcpClient.SendMessage(MACPlayer + " mixer volume ?\n");
TcpClient.SendMessage(MACPlayer + " title ?\n");
Pause(3);
TcpClient.Disconnect();

February 25, 2015, 08:47:52 PM
Reply #10

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
I didn't create widget at all, and create program or variable only use in same program. So i can't help a lot on that ...

February 25, 2015, 10:03:33 PM
Reply #11

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
Great,
my squeeze box now speak  ;D

- alarm activated (status.level)
- alarm deactivated (status.level)
- alarm (homeGenie.SecurityTriggered)

I attach the code

Code: [Select]

var remoteServer = Program.InputField("LMSServer").Value;
    var remotePort = Program.InputField("LMSPort").Value;
    var MACPlayer = Program.InputField("MACPlayer").Value;
   

// FUNCTION PARSE VARIABLES
    Action<string> HandleMessageReceived = (string message) => {
      string[] msg = ((string)message).Split(' ');
            switch(msg[1])
              {
                case "power":
                if (string.Compare(Program.Parameter("squeezebox.power").Value,msg[2]) != 0) {
                    Program.Parameter("squeezebox.power").Value = msg[2];
                }
              break;
                case "mixer":
                if (string.Compare(Program.Parameter("squeezebox.volume").Value,msg[3]) != 0 && string.Compare(msg[2], "volume")==0) {
                    Program.Parameter("squeezebox.volume").Value = msg[3];
                    Program.RaiseEvent("squeezebox.volume", msg[3], "Squeeze box Volume");
                }
              break;
                case "title":
                if (string.Compare(Program.Parameter("squeezebox.title").Value,msg[2]) != 0 ) {
                    Program.Parameter("squeezebox.title").Value = msg[2];
                }
              break;
              }

   
    };
        TcpClient.OnStringReceived( HandleMessageReceived ); 
TcpClient.EndOfLine = "\n";
TcpClient.Service( remoteServer );
        TcpClient.Connect( 9090 );
       
Func<string, bool> Squeeze=  (string command) =>
        {
            TcpClient.SendMessage(MACPlayer + " " + command + "\n");
            return true;
        };

Func<string, bool> SqueezeSpeak=  (string command) =>
        {
            TcpClient.SendMessage(MACPlayer + " playlist play http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=" + command + "&tl=en&total=1&idx=0&textlen=255\n");
            return true;
        };

// POLLING VARIABLE
    Squeeze ("power ?");
Squeeze ("mixer volume ?");
Squeeze ("title ?");
Pause(1);

// ALARM ACTIVATED / DEACTIVATED
if (string.Compare(Modules.WithName("Security Alarm System").Get().Parameter("Status.Level").Value, Program.Parameter("squeezebox.alarmActive").Value)!= 0 ){
          Squeeze ("power 1");
          Squeeze ("mixer volume 60");
          if (Modules.WithName("Security Alarm System").Get().Parameter("Status.Level").Value == "1") {
          SqueezeSpeak ("Alarm%20activated");
             } else {
SqueezeSpeak ("Alarm%20deactivated");
          }
          Program.Parameter("squeezebox.alarmActive").Value = Modules.WithName("Security Alarm System").Get().Parameter("Status.Level").Value;
    Pause(3);
          Squeeze ("mixer volume " + Program.Parameter("squeezebox.volume").Value);
        }

if (Modules.WithName("Security Alarm System").Get().Parameter("HomeGenie.SecurityTriggered").Value == "1") {
          Squeeze ("power 1");
          Squeeze ("mixer volume 60");
            SqueezeSpeak ("Alarm");
        Pause(5);
          Squeeze ("mixer volume " + Program.Parameter("squeezebox.volume").Value);     
        }
Pause(3);
TcpClient.Disconnect();

February 26, 2015, 05:38:51 PM
Reply #12

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544

March 02, 2015, 09:59:04 PM
Reply #13

igorrobertifoc

  • ***
  • Information
  • Full Member
  • Posts: 65
Hello,
I create a switch virtual device that enable the speaking of squuezebox.
My problem is the widget of the switch that not receive the status set.
Can some one Help me?

I attach the software.

Thank you in advance

March 02, 2015, 10:17:52 PM
Reply #14

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi,
What should show or do the widget ?
Bye