Tag Archives: LUA

Control of the Logitech Media Server using the LogicMachine

I use the Logitech Media Server to stream multi-room audio in our apartment. Lately I wanted to be able to also control the Spotify Plugin from the KNX buttons at home and automate some tasks.

This is a simple user library to allow you to send commands to a player attached to your LMS.

--Functions for Logitech Media Server integration
squeezboxserverip = '192.168.178.2' -- IP of the Logitech Media Server

function unescape(space)
return string.gsub(space, ':', '%%3A') -- the telnet server returns : as %3A
end

function squeezeboxsendcommand(player,command,value)
socket=require('socket')
local client = socket.connect(squeezboxserverip, 9090)
playercommand = player .. ' ' .. command .. ' '
client:send(playercommand .. value .. '\n')
local result=client:receive()
status = string.sub(result, string.len(unescape(playercommand))) --remove the MAC and command to get to the answer
client:close()
os.sleep(0.2)
return(status)
end

function squeezeboxstatus(player)
socket=require('socket')
local client = socket.connect(squeezboxserverip, 9090)
playercommand = player .. ' status'
client:send(playercommand .. '\n')
local result=client:receive()
status = split(result, ' ')
--status = string.sub(result, string.len(unescape(playercommand))) --remove the MAC and command to get to the answer
client:close()
log(status)
return(status)
end

to play a Spotify Playlist you need to add this code to a KNX object.


require('user.squeezebox') --get the user library to access LMS

local player = 'b8:27:eb:ad:6b:c3' --set witch player to access

if (event.getvalue() == true) then
squeezeboxsendcommand(player, 'playlist', 'clear') -- reset any playlist
squeezeboxsendcommand(player, 'playlist add', 'spotify:user:1175125342:playlist:7yCDwOnYZTXFTYymXZxp0t') --get this command from the logs of the LMS when playing the Spotify playlist
squeezeboxsendcommand(player, 'playlist shuffle', 1) -- shuffle, if you want
squeezeboxsendcommand(player, 'play', '') -- now play the list
grp.write('11/6/1', 'Playing Spotify')
else
squeezeboxsendcommand(player, 'playlist', 'clear')
grp.write('11/4/0', false) --turn off player
end

LogicMachine control Pioneer AVR via telnet

I thought I’d share this work in progress, based on my previous post here. I am an amateur both in Lua and in KNX… so take with a huge grain of salt.

All these scripts do is open a socket to a defined IP and Port and send a telnet command… then add an “Enter”… then wait for an answer. It closes right after that, as the Pioneer does not like more than one telnet connection at a time and I don’t want to hog the port.

Copy this code into a user library. I called mine user.telnet

--Sends a single telnet command to a host and port
--it returns one line answer
function telnetsend(host, port, command)

 nextline = '\r\n'

 local socket = require("socket")
 local tcp = assert(socket.tcp())
 res, err = tcp:connect(host, port)
 res, err = tcp:send(command .. nextline)
 local answer = tcp:receive('*l')
 tcp:close()
 return answer
end

--Sets the volume to a numeric value
--takes into account, that Pioneer increments the volume in
--2 step intervals. Takes a host ip and port as input.
function setvolume(host, port, volumelevel)

 local currentvolume = getvolume(host, port)

 if volumelevel > currentvolume then
   for i = currentvolume, volumelevel -1, 2 do
     telnetsend(host,port,VOLUME_UP)
   end
 else
   for i = volumelevel, currentvolume-1, 2 do
     telnetsend(host,port,VOLUME_DOWN)
   end
 end
 
 currentvolume = getvolume(host, port)
 return currentvolume

end

--Returns the current volume
function getvolume(host, port)
 
 local currentvolume = tonumber(string.sub(telnetsend(host,port,VOLUME_QUERY), 5))
 return currentvolume
 
end

--Turns reciever on off
function soundonoff(host, port, onoff)
 if onoff == true then
   telnetsend(host,port,POWER_ON)
   local status = telnetsend(host,port,POWER_QUERY)
   if status == POWER_ONSTATE then
     return true
   else
     alert("Could not turn on sound")
   end    
 else
   telnetsend(host,port,POWER_OFF)
   local status = telnetsend(host,port,POWER_QUERY)
   if status == POWER_OFFSTATE then
     return false
   else
     alert("Could not turn off sound")
   end
 end
end

and put this code into a separate user.script. I called mine user.pioneer
Continue reading “LogicMachine control Pioneer AVR via telnet” »

LogicMachine telnet user script

The following code enables you to open a telnet connection and send commands. I use it to connect to my Pioneer sound system. Add it to a user script.

telnet-lm

-- send Telnet command

function telnet(host, port, command)
local socket = require("socket")
local tcp = assert(socket.tcp())
res, err = tcp:connect(host, port)
res, err = tcp:send(command)

while true do
local s, status, threebytes = tcp:receive(3)
if status == "closed" then break end
end
tcp:close()
end

Usage

All you need to do now is call the function from your KNX-Object script. Example:

require('user.telnet')
telnet('192.168.0.24', 8102, 'PF\r\n\r\nclose\r\n\r\n')

The PF command tells my Pioneer to turn off. I’m not sure if a close command is necessary, but all the returns are. The IP address and port have to be changed to what you need.

DMX LogicMachine Lights user library

I have been optimizing my DMX scripts for the LogicMachine. The following is a set of functions that will enable you to turn a set of DMX channels on/off.


-- set of variables for zones in the apartment
 alllights = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}

 bathroomlights = {7,8,20}
 livinglights = {5,6,9,10,11,12,14,15,16,17,18,19}
 kitchenlights = {13}
 bedroomlights = {1,2}
 entrancelights = {4}

-- turns DMX stripe to full on or off based on two groups
function dmxtoggle(channel, state)
 -- group that contains the value for ON
 on = grp.getvalue('5/7/17')
 -- group that contains the value for OFF
 off = grp.getvalue('5/7/18')
 if (state == true) then
  DMX.set(channel, on)
 else
  DMX.set(channel, off)
 end
end

-- loops through all lights
-- lights is an array of the channel(s) to be set
-- state is the state of the group
function dmxlooptoggle(lights, state)
 for index, value in ipairs(lights) do
  dmxtoggle(value, state)
 end
end

--Loops through an array of channels and sets them to a value
function dmxloopset(lights, value)
 for index, channel in ipairs(lights) do
  DMX.set(channel, value)
 end
end

To use it, create a user library, I called it mydmx. Then copy/paste the above code and change the variables to the light groups you want to switch together.

To then run it use the following code. The first line enables the above user library. Then the dmxlooptoggle is called to change the bathroom light to the value of the group (on/off). the last code updates a group that holds the status object (on/off).


require('user.mydmx')
dmxlooptoggle(bathroomlights, event.getvalue())
grp.write('5/7/24', event.getvalue())