Use LogicMachine as a TCP client for reading data from Home Theater #
Task #
- Establish TCP communication with external TCP server – Denon Home Theater
- Read from Denon and show on visualization:
– boolean object with Denon ON/OFF status
– string object with radio station currently playing
Resident script #
Add the following code into the resident script, set sleep time to 0.
-- first call
if not ready then
require('socket')
warningclosed = true
warningfailed = true
warningerrors = true
warningtimeou = true
denonstatus = false
lastdatareceived = nil
-- incoming command parser
function parse(data)
if data == 'PWON' then
denonstatus = true
elseif data == 'PWSTANDBY' then
denonstatus = false
elseif string.sub(data, 1, 4) == 'NSE0' then
grp.write('5/2/2', string.sub(data, 5))
elseif string.sub(data, 1, 4) == 'NSE1' then
grp.write('5/2/3', string.sub(data, 5))
else
-- log other info, not mapped, if useful
log(data)
end
-- check if Denon changed status and sent new Object value in the bus only for changes
currentdenonstatus = grp.getvalue('5/2/1')
if currentdenonstatus ~= denonstatus then
grp.write('5/2/1', denonstatus)
end
end
ready = true
end
-- client connected
if connected then
-- send status request, in order to keep the socket live
-- Denon sends PWON each second automatically on the socket, no request necessary
--client:send('PW?\r')
while true do
char, err = client:receive(1)
if char ~= nil then
lastdatareceived = os.time()
warningclosed = true
warningfailed = true
warningerrors = true
warningtimeou = true
else
now = os.time()
deltatime = now - lastdatareceived
end
-- error while receiving, timeout or closed socket
if err then
-- remote server closed connection, reconnect
if err == 'closed' then
connected = false
if warningclosed then alert('[tcp-client] connection closed') end
warningclosed = false
sleep(1)
elseif err == 'timeout' then
connected = false
if warningtimeou then alert('[tcp-client] connection timeout') end
warningtimeou = false
sleep(1)
elseif warningerrors then alert('[tcp-client] connection failed: %s', err)
warningerrors = false
end
break
-- end of line, parse buffer
elseif char == '\r' then
data = table.concat(buffer)
parse(data)
buffer = {}
-- wait some time before next request
--sleep(1)
break
-- other char, add to buffer
else
table.insert(buffer, char)
end
end
-- first call or previously disconnected
else
-- close previous connection when disconnected
if client then
client:close()
client = nil
end
-- create tcp client
client = socket.tcp()
client:settimeout(5)
connected, err = client:connect('172.16.1.111', 23)
-- connect ok, reset buffer
if connected then
lastdatareceived = os.time()
warningclosed = true
warningfailed = true
warningerrors = true
warningtimeou = true
alert('[tcp-client] connection ok')
buffer = {}
sleep(5)
-- error while connecting,
else
if warningfailed then alert('[tcp-client] connection failed (conn): %s', err) end
warningfailed = false
sleep(5)
end
end
LogicMachine output #
- TCP connection state – OK, closed, timeout, failed
- Log other info, not mapped, if useful
- Object values
Other Denon control protocol #
You can download Denon device protocol here to see what information you can receive from your player.
Created by Giovanni Aduso from Schüco