luup.devices[N].udn results in UUID?

I’ll be the first to admit that when it comes to UPnP, I’ve got a fairly long road to travel to even call myself novice. However, the wiki page for the luup.devices extension states that I should be getting the UDN (which I took to mean something along the lines of “urn:upnp-org:serviceId:SwitchPower1” and not the UUID which the following snippet of code returns:

local switchUDN = luup.devices[83].udn
luup.log("Switch UDN: " .. switchUDN)

Result in the LuaUPnP.log file.

 luup_log:35: Switch UDN: uuid:4d494342-5342-5645-0053-000000003130 <0x2c0c>

I was hoping to extract a service string so I could create a "setSwitchState(devID, state) function that takes a deviceID # and a state (“on” || “off”). Would that even be possible?

Although an UDN (Unique Device Name) has to start with ‘uuid:’, it doesn’t have to be an UUID.
An URN (Uniform Resource Name) is a URI (Uniform Resource Identifier) that uses the urn ‘scheme’.

You are looking for the luup.devices[ i ].device_type, which must be converted to the name of the corresponding service:

#define HADEVICE_SID      "urn:micasaverde-com:serviceId:HaDevice1"
#define HADEVICE_STYPE    "urn:schemas-micasaverde-com:service:HaDevice:1"

Remove ‘schemas-’, add ‘Id’ to the token between the 2nd and 3rd ‘:’ (not necessarily ‘service’), and remove the last ‘:’. Note that this algorithm may fail for plugins from http://code.mios.com/

I think the following will work for on/off switches, regardless of the actual device_type content, assuming the pattern doesn’t change(?!?):

        local devID = someNumericID
        local targetValue = <0 or 1>
        local str_devURN = luup.devices[devID].device_type
	str_devURN = string.gsub(devURN, '(%a+):(%a+%-)(%a+)%-(%a+):(%a+):(%a+):(%d)', '%1:%3-%4:%5Id:%6%7')
        luup.call_action(str_devURN, "SetTarget", { newTargetValue =  targetValue }, devID)

Agreed?

Turns out it didn’t work for all switches, so I modified it a little. And I suspect I’ll be modifying more as I go:

function convertURN( devURN )
	if ( (devURN:find('BinaryLight') ~= nil) )
	then
		devURN = string.gsub(devURN, 'BinaryLight', 'SwitchPower')
		devURN = string.gsub(devURN, 'device', 'service')
	end -- if
	devURN = string.gsub(devURN, '(%a+):(%a+%-)(%a+)%-(%a+):(%a+):(%a+):(%d)', '%1:%3-%4:%5Id:%6%7')
	return devURN
end -- function	

http://wiki.micasaverde.com/index.php/Luup_UPNP_Files has a list of device types and service ids. Please note that a device type can support more than one service id …

Another approach would be to map the device category to the corresponding services (see the LOUIS4Vera implementation file).