Use LM2 as TCP client for reading data from Home Theater
Example: Use LM2 as 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 program
- Add the following program into Resident script.
- -- 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
Logic Machine 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 on more what information you can receive from your player.
Created by Giovanni Aduso from Schüco