Hello,
Please find below a script to control Kodi over UDP.
I does simulate a full remote, so you can control the behaviour with remote.xml inside kodi.
Please check http://kodi.wiki/view/list_of_built-in_functions for the list of commands
To install it, just copy the script into a user librairy, then use kodi_button and kodi_action in your event script.
Some example :
kodi_button("R1","select")
kodi_action("Action(PlayPause)")
kodi_button("R1","up",0,1,1)
kodi_button("R1","up",1,0,1)
Best regards,
Matt
Please find below a script to control Kodi over UDP.
I does simulate a full remote, so you can control the behaviour with remote.xml inside kodi.
Please check http://kodi.wiki/view/list_of_built-in_functions for the list of commands
To install it, just copy the script into a user librairy, then use kodi_button and kodi_action in your event script.
Some example :
kodi_button("R1","select")
kodi_action("Action(PlayPause)")
kodi_button("R1","up",0,1,1)
kodi_button("R1","up",1,0,1)
Code:
--[[ Librairy : Kodi UDP control
Author : Matthieu Bouthors
Command reference http://kodi.wiki/view/list_of_built-in_functions
Change IP with your kodi server.
Verified with Kodi v16 and v17
This is a partial implementation, full implementation in python : https://github.com/xbmc/xbmc/blob/master/tools/EventClients/lib/python/xbmcclient.py
Some example :
kodi_button("R1","select")
kodi_action("Action(PlayPause)")
kodi_button("R1","up",0,1,1)
kodi_button("R1","up",1,0,1)
]]--
kodi_destination_IP = "192.168.1.1"
kodi_destination_port = "9777"
--conversion function
function int_to_raw_string(raw_integer,length)
local value = raw_integer
local str = ""
for i=1,length do
str = string.char(value % 256) .. str
value = math.floor(value / 256)
end
return str
end
-- execute kodi action
function kodi_action(action)
-- load namespace
local socket = require("socket")
-- create a new UDP object
local udp = assert(socket.udp())
--headers
--[[
-----------------------------
| -H1 Signature ("XBMC") | - 4 x CHAR 4B
| -H2 Version (eg. 2.0) | - 2 x UNSIGNED CHAR 2B
| -H3 PacketType | - 1 x UNSIGNED SHORT 2B
| -H4 Sequence number | - 1 x UNSIGNED LONG 4B
| -H5 No. of packets in msg | - 1 x UNSIGNED LONG 4B
| -H6 Payload size
| -H7 Client's unique token | - 1 x UNSIGNED LONG 4B
| -H8 Reserved | - 10 x UNSIGNED CHAR 10B
|---------------------------|
| -P1 payload | -
-----------------------------
]]--
local action_type = "\x02"
local payload = action_type .. action .. "\x00"
local version_maj = "\x02"
local version_min = "\x00"
local PT_ACTION = "\x00\x0A"
local seq_num = "\x00\x00\x00\x01"
local max_seq = "\x00\x00\x00\x01"
local payload_size = string.len(payload)
local unique_id = "LM01"
local reserved = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
header = "XBMC" .. version_maj .. version_min .. PT_ACTION .. seq_num .. max_seq .. int_to_raw_string(payload_size,2) .. unique_id .. reserved
-- contact host
assert(udp:sendto(header .. payload,kodi_destination_IP, kodi_destination_port))
end
-- simulate kodi button press
function kodi_button(map,name,release,repeating,queue)
-- load namespace
local socket = require("socket")
-- create a new UDP object
local udp = assert(socket.udp())
--headers
--[[
-----------------------------
| -H1 Signature ("XBMC") | - 4 x CHAR 4B
| -H2 Version (eg. 2.0) | - 2 x UNSIGNED CHAR 2B
| -H3 PacketType | - 1 x UNSIGNED SHORT 2B
| -H4 Sequence number | - 1 x UNSIGNED LONG 4B
| -H5 No. of packets in msg | - 1 x UNSIGNED LONG 4B
| -H6 Payload size
| -H7 Client's unique token | - 1 x UNSIGNED LONG 4B
| -H8 Reserved | - 10 x UNSIGNED CHAR 10B
|---------------------------|
| -P1 payload | -
-----------------------------
"""
Keyword arguments:
repeating -- this key press should repeat until released (default: 0)
Note that queued pressed cannot repeat.
down -- if this is 1, it implies a press event, 0 implies a release
event. (default: 1)
queue -- a queued key press means that the button event is
executed just once after which the next key press is
processed. It can be used for macros. Currently there
is no support for time delays between queued presses.
(default: 0)
map_name -- a combination of map_name and button_name refers to a
mapping in the user's Keymap.xml or Lircmap.xml.
map_name can be one of the following:
"KB" => standard keyboard map ( <keyboard> section )
"XG" => xbox gamepad map ( <gamepad> section )
"R1" => xbox remote map ( <remote> section )
"R2" => xbox universal remote map ( <universalremote>
section )
"LI:devicename" => LIRC remote map where 'devicename' is the
actual device's name
button_name -- a button name defined in the map specified in map_name.
For example, if map_name is "KB" refering to the
<keyboard> section in Keymap.xml then, valid
button_names include "printscreen", "minus", "x", etc.
amount -- unimplemented for now; in the future it will be used for
specifying magnitude of analog key press events
"""
]]--
local kodi_BT_USE_NAME = 0x01
local kodi_BT_DOWN = 0x02
local kodi_BT_UP = 0x04
local kodi_BT_USE_AMOUNT = 0x08
local kodi_BT_QUEUE = 0x10
local kodi_BT_NO_REPEAT = 0x20
local kodi_BT_VKEY = 0x40
local kodi_BT_AXIS = 0x80
local kodi_BT_AXISSINGLE = 0x00
local flags = kodi_BT_USE_NAME
if (release == 1) then
flags = flags + kodi_BT_UP
else
flags = flags + kodi_BT_DOWN
end
if (not repeating) then
flags = flags + kodi_BT_NO_REPEAT
end
if (queue) then
flags = flags + kodi_BT_QUEUE
end
local payload = "\x00\x00" .. int_to_raw_string(flags,2) .. "\x00\x00" .. map .. "\x00" .. name .. "\x00"
local kodi_version_maj = "\x02"
local kodi_version_min = "\x00"
local kodi_PT_BUTTON = "\x00\x03"
local seq_num = "\x00\x00\x00\x01"
local max_seq = "\x00\x00\x00\x01"
local payload_size = string.len(payload)
local kodi_unique_id = "LM01"
local kodi_reserved = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
header = "XBMC" .. kodi_version_maj .. kodi_version_min .. kodi_PT_BUTTON .. seq_num .. max_seq .. "\x00" .. string.char(payload_size) .. kodi_unique_id .. kodi_reserved
-- contact host
assert(udp:sendto(header .. payload,kodi_destination_IP, kodi_destination_port))
end
Best regards,
Matt