PDA

View Full Version : Control Sony BDV-T58



yonu
July 7th, 2012, 09:12 PM
ok I am trying to control a new Sony bdv-T58 Bluray home theater using Girder and am not sure where to start it is a wifi connected device and if fully controllable via android and iphone remotes so I assume there is a way to send the data to it from girder.

Thanks,
Yonu

Tieske8
July 8th, 2012, 07:07 AM
Saw your post on the xPL forum. The Sony BDV-T58 has DLNA/UPnP capabilities if I'm correct. so you should be able to control it through UPnP.

See this thread (http://www.promixis.com/forums/showthread.php?21127-UPnP-and-Girder)

yonu
July 8th, 2012, 11:04 AM
Thanks I had read some on the gateway but wasn't sure it was what I needed so I may be bothering you some but it seems to be what I need

Thanks,
Yonu

yonu
July 8th, 2012, 12:34 PM
Ok quick question I am getting the data from the Bluray. Now the big question can I transmit commands back to it?

Thanks,
Yonu

Tieske8
July 8th, 2012, 02:10 PM
Sure you can. Check the forum thread on UPnP, and this tutorial (http://www.thijsschreijer.nl/blog/?p=569).

yonu
July 8th, 2012, 10:34 PM
hey thanks for the info the tutorial and all makes sense however I am hoping you can tell me where I have screwed up it says I have an error on line 2

Here is the error
[string "udp-server.gml:\test\Scripting"]:2: in main chunk

and here is my code

-- Setup persistent device adn service IDs
local BVDT58 = UPnP.device["00000000-0000-1010-8000-f0bf97fcad4c"]
local Mute = BVDT58.services["urn_upnp-org_serviceId_RenderingControl"]

-- define global and methods to export
BVDT58 = {

Unmute = function (self)
return Mute.methods.SetTarget:execute(true)
end,

mute = function (self)
return Mute.methods.SetTarget:execute(false)
end,

Dim = function (self, level)
return Mute.methods.SetLoadLevelTarget:execute(level)
end,

Status = function (self)
local load = Mute.variables.Volume.value .. "%"
if Mute.variables.Status.value == "False" then
print("Light is currently off.")
else
print("Light is currently on at " .. load)
end
end,
}

yonu
July 8th, 2012, 11:01 PM
I just realized I didn't have the whole error in the post the rest is

[string "udp-server.gml:\test\Scripting"]:2: attempt to index field `device' (a nil value)

Tieske8
July 9th, 2012, 04:06 AM
In Lua a variable can hold any value. Lua tables are basically a key-value list, anything can be a key and anything can be a value.

The UPnP code cretaes a global variable, UPnP, which is a table which holds several core elements. a.o. the 'devices' table. Now whenever you request a table from a table using a key that does not exist, Lua will return 'nil' (similar to NULL or Nothing in other languages).


-- Setup persistent device adn service IDs
local BVDT58 = UPnP.device["00000000-0000-1010-8000-f0bf97fcad4c"]
local Mute = BVDT58.services["urn_upnp-org_serviceId_RenderingControl"]

You wrote 'UPnP.device' instead op 'UPnP.devices', so; 'UPnP.device' returns nil, because the key 'device' does not exist. Then Lua will try to lookup the key "00000000-0000-1010-8000-f0bf97fcad4c" in the value nil (which is not a table).
This results in the valid error:
attempt to index field `device' (a nil value)

So change;

-- Setup persistent device adn service IDs
local BVDT58 = UPnP.device["00000000-0000-1010-8000-f0bf97fcad4c"]
local Mute = BVDT58.services["urn_upnp-org_serviceId_RenderingControl"]


into;


-- Setup persistent device and service IDs
if not UPnP then
print("UPnP global table not found")
return
end
if not UPnP.devices then
print("UPnP device list not found")
return
end
local BVDT58 = UPnP.devices["00000000-0000-1010-8000-f0bf97fcad4c"]
if not BVDT58 then
print("UPnP device BVDT58 not found")
return
else
print ("UPNP device BVDT58 found")
end
if not BVDT58.services then
print("UPnP device BVDT58 has no services defined")
return
end
local Mute = BVDT58.services["urn_upnp-org_serviceId_RenderingControl"]
if not Mute then
print("UPnP device BVDT58 RenderingControl not found")
return
else
print ("UPNP device BVDT58 RenderingControl found")
end



(did this top of my head, had no way to test it here)

yonu
July 9th, 2012, 12:51 PM
ok that code solved that issue now I hate to ask I get this [string "Interactive"]:1: `=' expected near `mute'

everytime I try to run any of the functions however I know I have very little LUA knowlegde but the syntax looks right but here is the code

Status = function (self)
local load = Mute.variables.Mute.event .. "%"
if Mute.variables.Status.event == "False" then
print("Light is currently off.")
else
print("Light is currently on at " .. load)
end

Tieske8
July 9th, 2012, 02:04 PM
Have you finished the tutorial? The code posted abobe uses 'LoadLevelTarget' etc. these names are used for a dimmable light device, not for media renderers.
Use the variable explorer to find the UPnP.devices list and explore your device, there you'll find the appropriate action/method names for your device

yonu
July 9th, 2012, 02:18 PM
I have been changing the lines one by one but I will go ahead and change the all and try it again. Oki just looked again I see what you are talking about I changed one line in the code but not the other I will test it in a few

Thanks,
yonu

yonu
July 9th, 2012, 03:41 PM
ok I may have found issue but I am alittle confused on how to write the line for this section

Unmute = function (self)
return Mute.methods.SetMute:execute(true)
end,

based on devicespy I have several variables to pass here is the table from SetMute

Action name SetMute
Argument 1 (ui4) InstanceID
Argument 1 ASV A_ARG_TYPE_InstanceID
Argument 2 (string) Channel
Argument 2 ASV A_ARG_TYPE_Channel
Argument 3 (boolean) DesiredMute
Argument 3 ASV Mute
Return argument <none>


Sorry to be a pain.,
yonu

Tieske8
July 9th, 2012, 05:01 PM
can you post the service xml? (in devicespy right-click the service and pick the right option)

yonu
July 9th, 2012, 05:03 PM
sure here it is

<?xml version="1.0" ?>
- <scpd xmlns="urn:schemas-upnp-org:service-1-0">
- <specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
+ <actionList>
- <action>
<name>ListPresets</name>
- <argumentList>
- <argument>
<name>InstanceID</name>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
<direction>in</direction>
</argument>
- <argument>
<name>CurrentPresetNameList</name>
<relatedStateVariable>PresetNameList</relatedStateVariable>
<direction>out</direction>
</argument>
</argumentList>
</action>
- <action>
<name>SelectPreset</name>
- <argumentList>
- <argument>
<name>InstanceID</name>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
<direction>in</direction>
</argument>
- <argument>
<name>PresetName</name>
<relatedStateVariable>A_ARG_TYPE_PresetName</relatedStateVariable>
<direction>in</direction>
</argument>
</argumentList>
</action>
- <action>
<name>GetMute</name>
- <argumentList>
- <argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
- <argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
- <argument>
<name>CurrentMute</name>
<direction>out</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
- <action>
<name>SetMute</name>
- <argumentList>
- <argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
- <argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
- <argument>
<name>DesiredMute</name>
<direction>in</direction>
<relatedStateVariable>Mute</relatedStateVariable>
</argument>
</argumentList>
</action>
- <action>
<name>GetVolume</name>
- <argumentList>
- <argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
- <argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
- <argument>
<name>CurrentVolume</name>
<direction>out</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
- <action>
<name>SetVolume</name>
- <argumentList>
- <argument>
<name>InstanceID</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
</argument>
- <argument>
<name>Channel</name>
<direction>in</direction>
<relatedStateVariable>A_ARG_TYPE_Channel</relatedStateVariable>
</argument>
- <argument>
<name>DesiredVolume</name>
<direction>in</direction>
<relatedStateVariable>Volume</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
- <serviceStateTable>
- <stateVariable sendEvents="yes">
<name>LastChange</name>
<dataType>string</dataType>
</stateVariable>
- <stateVariable sendEvents="no">
<name>PresetNameList</name>
<dataType>string</dataType>
</stateVariable>
- <stateVariable sendEvents="no">
<name>A_ARG_TYPE_Channel</name>
<dataType>string</dataType>
- <allowedValueList>
<allowedValue>Master</allowedValue>
</allowedValueList>
</stateVariable>
- <stateVariable sendEvents="no">
<name>Mute</name>
<dataType>boolean</dataType>
</stateVariable>
- <stateVariable sendEvents="no">
<name>Volume</name>
<dataType>ui2</dataType>
- <allowedValueRange>
<minimum>0</minimum>
<maximum>100</maximum>
<step>1</step>
</allowedValueRange>
</stateVariable>
- <stateVariable sendEvents="no">
<name>A_ARG_TYPE_InstanceID</name>
<dataType>ui4</dataType>
</stateVariable>
- <stateVariable sendEvents="no">
<name>A_ARG_TYPE_PresetName</name>
<dataType>string</dataType>
- <allowedValueList>
<allowedValue>FactoryDefaults</allowedValue>
</allowedValueList>
</stateVariable>
</serviceStateTable>
</scpd>

Tieske8
July 10th, 2012, 09:35 AM
ok I may have found issue but I am alittle confused on how to write the line for this section
Unmute = function (self)
return Mute.methods.SetMute:execute(true)
end,
based on devicespy I have several variables to pass here is the table from SetMute


Action name SetMute
Argument 1 (ui4) InstanceID
Argument 1 ASV A_ARG_TYPE_InstanceID

Unsigned Integer value, I haven't read the DCP for the mediarenderer lately, but I think the default for the instance ID is '0' (the instance ID is relevant for devices with multiple renderers, eg. a TV set with a picture-in-picture control)



Argument 2 (string) Channel
Argument 2 ASV A_ARG_TYPE_Channel

The xml states:


<allowedValueList>
<allowedValue>Master</allowedValue>
</allowedValueList>

so that's easy; "Master" is the only possible value



Argument 3 (boolean) DesiredMute
Argument 3 ASV Mute

This is a boolean, which can be sent as a Lua boolean; true

Return argument <none>

Sorry to be a pain.,
yonu

so try this;


Unmute = function (self)
return Mute.methods.SetMute:execute(0, "Master", true)
end,

yonu
July 10th, 2012, 03:00 PM
ok here is what I have in the scrpting block I get the found lines in the console for the first part but when I run the lines for unmute that you just sent I get this error [string "Interactive"]:1: `=' expected near `Unmute'

here is the code
-- Setup persistent device and service IDs
if not UPnP then
print("UPnP global table not found")
return
end
if not UPnP.devices then
print("UPnP device list not found")
return
end
local BVDT58 = UPnP.devices["00000000-0000-1010-8000-f0bf97fcad4c"]
if not BVDT58 then
print("UPnP device BVDT58 not found")
return
else
print ("UPNP device BVDT58 found")
end
if not BVDT58.services then
print("UPnP device BVDT58 has no services defined")
return
end
local T58 = BVDT58.services["urn_upnp-org_serviceId_RenderingControl"]
if not T58 then
print("UPnP device BVDT58 RenderingControl not found")
return
else
print ("UPNP device BVDT58 RenderingControl found")
end

-- define global and methods to export
BVDT58 = {

Unmute = function (self)
return T58.methods.SetMute:execute(0, "Master", true)
end,

}

Thanks and yes I am a pain,
yonu

Tieske8
July 10th, 2012, 06:12 PM
Try this;


-- Setup persistent device and service IDs if not UPnP then
print("UPnP global table not found")
return
end

if not UPnP.devices then
print("UPnP device list not found")
return
end

local MyDevice = UPnP.devices["00000000-0000-1010-8000-f0bf97fcad4c"]

if not MyDevice then
print("UPnP device BVDT58 not found")
return
else
print ("UPNP device BVDT58 found")
end

if not MyDevice.services then
print("UPnP device BVDT58 has no services defined")
return
end

local MyService = MyDevice.services["urn_upnp-org_serviceId_RenderingControl"]

if not MyService then
print("UPnP device BVDT58 RenderingControl not found")
return
else
print ("UPNP device BVDT58 RenderingControl found")
end

-- define global and methods to export
BVDT58 = {

Unmute = function (self)
return MyService.methods.SetMute:execute(0, "Master", true)
end,

}


I think the names where messed up. Run this script first, that will create the global. Then from the console execute; BVDT58.Unmute()

yonu
July 12th, 2012, 09:19 PM
hey thanks that code did exactly what I need and you wee right I have my names screwy I set and looked over what I posted


ok I need to ask a simple question I have this block of code so that it should work but I have a slight issue but it isn't the code persay what is is is the return from the variable vd. here is the code
Voldown = function (self)
vd = MyService.methods.GetVolume:execute(0, "Master", 0)
print (vd)
if vd<0 then
nvd = vd - 5
print (nvd)
MyService.methods.SetVolume:execute(0, "Master", nvd)
return
else
end

based on what is showing in the xpl gateway window it is returning more than the volume valure here is the text from the gateway window however all I need is the 47 I just can't seem to get it I am getting returned true or false

21:55:18.013 Received MethodCall command from tieske-girder.pvr
21:55:18.015 Method: GetVolume, unique id: 13
21:55:18.253 Returned:
21:55:18.255 CurrentVolume = 47

Thanks,
yonu

Tieske8
July 13th, 2012, 12:19 AM
Just top of my head; the first return value (Lua can have multiple return values!!) is true/false indicating success or failure of the action, use a print statement to check this;


print( MyService.methods.GetVolume:execute(0, "Master", 0))


Then to get the volume (depending on the outcome of the print statement) use something like this;


-- success will be true/false
-- vd will have the returned volume, or possible an error if success is false
succes, vd = MyService.methods.GetVolume:execute(0, "Master", 0)


Use the print statement first, I'm not sure about the return values ...