VanVan / phantom-remote-control

HTTP Adapter to control Devialet Phantom Speakers (Play, Pause, Volume etc.)
GNU General Public License v3.0
15 stars 6 forks source link

Set volume not working #1

Open fwestenberg opened 4 years ago

fwestenberg commented 4 years ago

First of all thanks for all your work! I'm really glad someone started working on this! Personally I'd like to create a Home Assistant integration for this, but first I need to get it all working locally. I have two Phantom Silver's with DOS2 (no Dialog). When I run the index.js it finds one of the Phantoms (configured as stereo pair). Playing a sound goes well, in Stereo also. It also finds the actual volume level, but I'm not able to set a volume level. Any thoughts what might be wrong? Thanks again!

VanVan commented 3 years ago

Hi, I answer late, have you managed in the meantime to make the volume change work? I am personally still under DOS1, I was waiting for the arrival of a Windows application to make the change. It already happened that the volume change did not work, in this case, a restart of the Dialog fixed the problem. Did you try restarting the Phantom in your case ?

fwestenberg commented 3 years ago

Hi, Still not managed to fix this. I rebooted the speakers several times, but volume is not changing. Are you also able to change the volume when another source than upnp is used? Optical for example? Meanwhile I started a project to control the speakers using the protobuf's used in the Devialet app. No luck so far!

VanVan commented 3 years ago

I can confirm that the volume change works with any source on the Devialet (Optical, bluetooth, streaming...), which is why I designed it in the first place. I use it daily to change the volume of the speakers from a shortcut from the keyboard volume keys. However, I have not tested it on DOS2. When the volume doesn't change it, do you have an error reported, or does the application return a volume change success but no effect?

fwestenberg commented 3 years ago

I just tested with bubble upnp for android. When I play music using upnp, volume control via upnp (from this app) works. When I select another source in the Devialet app, upnp volume control does not work anymore. So it seems upnp volume only controls the upnp source volume from the speakers. :-(

VanVan commented 3 years ago

Interesting, if it's the case, it would be related to the upgrade to DOS2, I'm even less likely do upgrade quickly :) We should check with Devialet protocol for their remote or their mobile app.

fwestenberg commented 3 years ago

The mobile app use protobuf. Check out my library for more info, some parts are working like discovery. The remote I don't know. I guess bluetooth but I don't own a remote.

TonyTromp commented 3 years ago

Hi, Any update on this excellent work? I am unable to connect using the latest firmware. It hangs in a look saying: Detected device ip: x.x.x.x , but then doesnt seem to do anything.

VanVan commented 3 years ago

Hi, @TonyTromp What is your DOS version of your Devialet ?

fwestenberg commented 3 years ago

@VanVan, this is interesting! I talked to someone claiming Roon is always able to control volume (even when for example optical is used as source). So I downloaded Roon, took a trial and checked the traffic with wireshark. On the network I see this kind of conversation:

...................................................-.......U{"request":"subscribe_transport"}...c.......V{"request":"subscribe_controls","controller_id":"cxxxxxf-2x0x-4xxb-8xx0-fecd7xxxxxx8"}

...........V.{"action":"Changed","controls":{"source":{"info":{},"value":"not_selected"},"volume":{"min":0.0,"type":"number","value":60,"step":1.0,"mute":false,"max":100.0,"info":{}}},"status":"Success"}

...........W{"request":"update_transport","quiet":true,"status":{"loop":"disabled","shuffle":false,"state":"stopped","seek":null,"is_previous_allowed":false,"is_next_allowed":false,"is_pause_allowed":false,"is_play_allowed":false,"is_seek_allowed":false}}

...........W.{"quiet":true,"status":"Success"}

...........2.......X{"request":"update_volume","value":61}

...!.......X.{"status":"Success"}.............{"action":"Changed","controls":{"source":{"info":{},"value":"not_selected"},"volume":{"min":0.0,"type":"number","value":61,"step":1.0,"mute":false,"max":100.0,"info":{}}},"status":"Success"}...........8.{"action":"Changed","controls":{"source":{"info":{},"value":"not_selected"},"volume":{"min":0.0,"type":"number","value":61,"step":1.0,"mute":false,"max":100.0,"info":{}}},"status":"Success"}...........V.{"action":"Changed","controls":{"source":{"info":{},"value":"not_selected"},"volume":{"min":0.0,"type":"number","value":61,"step":1.0,"mute":false,"max":100.0,"info":{}}},"status":"Success"}...........S.{"action":"Changed","controls":{"source":{"info":{},"value":"not_selected"},"volume":{"min":0.0,"type":"number","value":61,"step":1.0,"mute":false,"max":100.0,"info":{}}},"status":"Success"}

If you download the Roon server for Linux, extract and search for Devialet there is a DLL. I will attach the code, extracted with dotPeek.

Devialet Roon.txt

Maybe we can create some integration with help of this code?

TonyTromp commented 3 years ago

This is great stuff! We just need to find the endpoint url and we should be able to interact using simple Rest Api it seems. I know the Reactor Custom has a API, maybe the interface is same. I will install roon and try with .netPeek also.

VanVan commented 3 years ago

Indeed, this is a great way to go ! I had searched for such an API at the time without success, I guess it was implemented on DOS2 and not before, is this your version?

TonyTromp commented 3 years ago

I found soimething worth while here: https://github.com/RoonLabs/roon-extension-devialet-phantom-volume/blob/master/app.js

Clone that code, and run:

npm install node app.js

to run it.

If you change the line in the Discover() method

if (desc.manufacturer == "Devialet" && desc.modelName == "Devialet UPnP Renderer") {

INTO

if (desc.manufacturer == "Devialet" && desc.modelName.toLowerCase().indexOf('phantom')>=0 ) {

it will actually find and connect to the Phantom Reactor in my case. We hopefully should be able to control the volume through UPnP now (need to check the Remote functions). We can wrap our own HTTP listener around it for simplfied control.

TonyTromp commented 3 years ago

OK.. I played around with the Roon code, there is one caveat it seems. Controlling the volume only works when in UPnP or Roon mode. It does not seem to adjust the volume if you are using Spotify.

console.log('Remote');
console.log(r);
var volume;
volume = await r.getVolume();
console.log(volume);
await r.setVolume(5);
var mute;
mute = await r.getMute();
console.log(mute);

await r.setMute(1);
fwestenberg commented 3 years ago

I tried the same, my Phantom's are on DOS2. But when I play uring Optical in, volume change also does not work. That's what I like about the Roon API I attached before: they do work with optical (and probably spotifiy too).

VanVan commented 3 years ago

This is indeed the change, I am still in DOS1, and the volume change (UPnP) still works, even in optical. The code you just tried works indeed on the same principle as the one I wrote, the API solution seems better if confirmed, I haven't tested it yet, and I'm not sure it works in DOS1 but it seems to be the right direction to take.

fwestenberg commented 3 years ago

I found there are two different .net files with Devialet coding in the Roon extension. The discovery also looks a bit different. Devialet DLL 2.txt

But for some reason the discovery from Python3 is not working with this code. Any clue?

import socket

    #  THIS IS CODE FROM THE ROON .NET FILE:
    #
    #   this._sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    #   this._sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
    #   this._sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
    #   this._sock.Bind((EndPoint) new IPEndPoint(IPAddress.Any, 45454));
    #   this._ReadLoop(this._sock, new byte[4096]);

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

print("Starting discovery...")

client.bind(('0.0.0.0', 45454))

while True:
    data, addr = client.recvfrom(4096)
    print("received message: %s" %data)
fwestenberg commented 3 years ago

I run this from Linux, seem to make a difference for socket.SO_REUSEADDR

fwestenberg commented 3 years ago

@TonyTromp your Phantom(s) are on DOS2, right? Can you install Roon (take a trial period), connect with the phantom and check the Roon log? The log location is shown here: https://desk.zoho.com/DocsDisplay?zgId=697775904&mode=inline&blockId=fklv02ccd98976e6a46a29fb8c12e6468bd9c

In the logging, you can search for the text Devialet. It will show you the port and some other stuff. Please post your port here.