Category Archives: Logic Machine

Posts about the Logic Machine re:actor I use for home automation

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 script to turn on off Epson projector

Today I created a small script in a KNX object to turn my Epson projector on off via a serial link.

require('serial')
-- device on the LogicMachine connected to the Epson projector
-- ttyUSB0 is typical for a USB RS-232C
-- tested with adapter based on FT232 or CP210x chip.
device = '/dev/ttyUSB0'
-- opens a serial port using the sugested values of Epson manual
-- https://support.math.unipd.it/sites/default/files/epson_emp_835.pdf
port = serial.open(device, { baudrate = 9600, parity = 'none', stopbits = 1  })

-- get value of KNX object
value = event.getvalue()

if (value == true) then
 -- send power on command with returns to make them stick
 char = "PWR ON\r\n"  
 port:write(char)
else
 -- send power off command
 char = "PWR OFF\r\n"  
 port:write(char)
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.