Ok, here it is:
-
Save the following code as /etc/cmh-ludl/I_DenonDimmer.xml and set the appropriate IP address in this file.
-
Manually create a new device (Apps / Develop Apps / Create device) with:
. device type: urn:schemas-upnp-org:device:DimmableLight:1
. device file: D_DimmableLight1.xml
. implementation file: I_DenonDimmer.xml
-
Reload the interface if needed, you should see the dimmer 
-
To send commands from a scene, use the following luup code:
luup.call_action(“urn:micasaverde-com:serviceId:HaDevice1”, “Poll”, {command = “PWON MV10 ZMFAVORITE1”}, )
(replace with the id of the dimmer you just created. You can send multiple commands in a single call by separting them with a space.
No need for my previous code, you can remove it as it’s redundant.
If you want a Zone ON/OFF functionnality, you may use virtual switches devices (and call the appropriate luup code upon state change).
Let me know how it goes for you!
[tt]<?xml version="1.0"?>
local socket = require "socket"
local denon_tcp
local denon_ip = "<ip address>"
function logDenon(msg)
luup.log("DENON: " .. msg)
end
function connectDenon()
if denon_tcp then
logDenon("Already connected")
return false
else
logDenon("Connecting...")
denon_tcp = assert(socket.tcp())
denon_tcp:settimeout(0.5)
local status, error = denon_tcp:connect(denon_ip, 23)
if status then
--logDenon("Connected")
return true
else
denon_tcp = nil
logDenon("Error connecting: " .. error)
return false
end
end
end
function sendDenon(cmd)
local buf = "", s, status, partial
status = nil
logDenon("Sending " .. cmd)
denon_tcp:settimeout(0)
buf, status, partial = denon_tcp:receive(9999)
denon_tcp:settimeout(0.1)
denon_tcp:send(cmd .. "\r")
buf, status, partial = denon_tcp:receive(9999)
if status then
buf = partial
if status ~= "timeout" then
logDenon("Error receiving: " .. status .. ", partial: " .. partial)
end
end
buf = string.gsub(buf, "\r", "")
logDenon("Received " .. buf)
sleepDenon()
return buf
end
function disconnectDenon()
--logDenon("Disconnecting...")
denon_tcp:close()
denon_tcp = nil
logDenon("Disconnected")
end
function sleepDenon()
luup.sleep(500)
end
function powerOnDenon()
local pw_status = sendDenon("PW?")
if pw_status == "PWSTANDBY" then
sendDenon("PWON")
sleepDenon()
else
logDenon("Not powering on, current status is " .. pw_status)
end
end
function powerOffDenon()
sendDenon("PWSTANDBY")
end
function initDenon(lul_device)
if connectDenon() then
updateDenonStatus(tonumber(lul_device))
disconnectDenon()
end
luup.call_timer('initDenon', 1, "5m", "", lul_device)
end
function updateDenonStatus(lul_device)
local pw_status = sendDenon("PW?")
if pw_status == "PWSTANDBY" then
luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", "0", lul_device)
elseif pw_status == "PWON" then
luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", "1", lul_device)
end
local mv_status = sendDenon("MV?")
local vol_string = string.match(mv_status, "MV(%d*)")
local vol = tonumber(vol_string)
if vol then
if string.len(vol_string) > 2 then
vol = vol / 10
end
local vol_max = tonumber(string.match(mv_status, "MVMAX *(%d*)"))
if vol_max then
luup.variable_set("urn:upnp-org:serviceId:Dimming1", "LoadLevelStatus", tostring(math.floor(vol*100/vol_max)), lul_device)
end
end
luup.variable_set("urn:micasaverde-com:serviceId:HaDevice1", "LastUpdate", os.time())
end
initDenon
<action>
<serviceId>urn:upnp-org:serviceId:SwitchPower1</serviceId>
<name>SetTarget</name>
<run>
if connectDenon() then
if lul_settings.newTargetValue == "1" then
powerOnDenon()
else
powerOffDenon()
end
updateDenonStatus(lul_device)
disconnectDenon()
end
</run>
</action>
<action>
<serviceId>urn:upnp-org:serviceId:Dimming1</serviceId>
<name>SetLoadLevelTarget</name>
<run>
if connectDenon() then
local mv_status = sendDenon("MV?")
local vol = tonumber(lul_settings.newLoadlevelTarget)
if vol then
if vol == 0 then
powerOffDenon()
elseif vol == 100 then
powerOnDenon()
else
local vol_max = tonumber(string.match(mv_status, "MVMAX *(%d*)"))
if vol_max then
local vol_percent = math.floor((vol * vol_max / 100) * 2) / 2
local vol_string = string.format("%02i", math.floor(vol_percent))
if (vol_percent - math.floor(vol_percent) > 0) then
vol_string = vol_string .. math.floor((vol_percent - math.floor(vol_percent)) * 10)
end
sendDenon("MV" .. vol_string)
end
end
end
updateDenonStatus(lul_device)
disconnectDenon()
end
</run>
</action>
<action>
<serviceId>urn:micasaverde-com:serviceId:HaDevice1</serviceId>
<name>Poll</name>
<run>
if connectDenon() then
if lul_settings.command then
local cmd
for cmd in string.gmatch(lul_settings.command, "%S+") do
sendDenon(cmd)
end
end
updateDenonStatus(lul_device)
disconnectDenon()
end
</run>
</action>
[/tt]