I have an GigaBlue Enigma 2 satellite box. This a Linux device which can be controlled by a web based UI https://dream.reichholf.net/e2web/
Enigma2 Linux boxes are manufactured by a number of companies under the name VU+, Dreambox, Gigablue, etc
I wanted to control the set-top box via virtual switches . An on/off switch to control the standby and a selector switch to change channels
I soon discovered the limitation of using a selector switch. You can only have 10 levels ! Although the selector switch will accept more levels only the first 10 are activated.
To get round this issue I created a number of selector switches (10 levels maximum) and split them into categories
Movies, Music,News , etc.
Creating the switches was easy just add dummy hardware (Enigma2) via the hardware tab and create the virtual switches One off/on switch and as many selector switches as required for the categories.
Using the Enigma2 web UI it was easy to add the HTTP calls directly to the switches ( change IP address as required).
On/Off Switch
on http://192.168.1.99/web/powerstate?newstate=4
off http://192.168.1.99/web/powerstate?newstate=5
Selector switches
Slightly more complicated to change TV channels as you need to know the service reference number for each channel. To obtain this information, put the following HTTP call into a web browser
http://192.168.1.99/web/getallservices
This will return all TV channels known to the setup box . copy the details of <e2servicename> and <e2servicereference> tags for each channel you want to use in the selector switches.
Ie BBC One HD and 1:0:19:22D9:80D:2:11A0000:0:0:0:
Please use the exact name of the TV channel you obtained from this list as Selector level name. This will be required later.
Now you can populate the selector switches with the correct data
Selector level name = BBC One HD
Selector level action =http://192.168.1.91/web/zap?sRef=1:0:19 ... 000:0:0:0:
You should now be able to change the TV channel and turn the box on and off via the switches.
There is a problem. If you have multiple selector switches for changing channels , they will not reset when a different channel is selected. Also if the channels are changed via the remote, again the switches will not show the correct details . To solve this issue I created two lua scripts. These scripts use the Enigma2 Web UI to obtain the current TV channel and power state of the the set-top box, then update the switches with the correct information.
Enigma
Code: Select all
-- This script is used in conjunction with Enigma-Scan to maintain selector switch status with Enigma 2 set-top boxes
--
-- This scripts scan the enigma 2 box to obtain current device state, and current current channel being viewed.
-- These are stored in the EnigmaStatus user variable.
--
-- This script relies on a least 2 virtual switches being created an on/off switch (to turn on/off the Enigma2 box) and a selector switch.
-- Each selector switch and the off/on switch must be pre-populated with the correct TV channels names and action URL.
--
-- ********Setup Selector Switch Instructions**********
--
-- Run the following HHTP call against the Enigma2 set-top box will obtain the correct information to populate the selector switch.
--
-- http://192.168.1.99/web/getallservices (where 192.168.1.99) is IP address of the Enigma 2 Box
--
-- This will return a complete list of all channels the Enigma 2 box recognises.
-- Note the following information :-
-- <e2servicename>
-- <e2servicereference> that matches the <e2servicename>.
--
-- Note due to limitation of selector switches they can only hold 10 levels. So create as many selector switches as required.
-- Each selector switch can hold a different category of Channels Entertainment, MOvies , Music , etc.
--
-- The Selector level in the selector switch must match the <e2servicename> exactly.
-- The Selector action in the selector switch uses the following syntax http://192.168.1.91/web/zap?sRef=<e2servicereference>.
--
-- *********Setup On/Off switch instructions **************
--
-- to turn the Enigma2 box :-
--
--on http://192.168.1.99/web/powerstate?newstate=4 (where 192.168.1.99 is the IP address of the Enigma2 box)
--off http://192.168.1.91/web/powerstate?newstate=5
--
--
--
-- The script will also automatically populate the EnigmaList(n) user variable(s) with the selector levels in the selector switch(es) created above.
-- One EnigmaList(n) user variable for each selector switch created above.
--
-- The following user variables must be created before the script is run.
--
-- EnigmaParams Multiple values to hold IP and switch details. Each value is separated by a |.
-- The position in the parameter list determines the role of the value.
--
-- 1 = * This is an optional value . If present will cause the script to delete and recreate the data
-- in EnigmaList(n) user variable(s). Once updated the script will remove the "*" .
-- 2 = Ip address of Enigma2 Box
-- 3 = On/Off switch IdX
-- 4+ = IdX(es) of selector switch(es) which hold channel list. One list for each switch value specified.
--
-- Example 192.168.1.99|45|47|49|50
-- Ip address,IdX of on/off switch that control Enigma2 power state,Idx of selector switches
--
-- Example *|192.168.1.99|45|47|49|50 as above but will cause EnigmaList(n) values to be regenerated
--
-- EnigmaList(n) Multiple variables to hold individual selector switch LevelNames.
-- One User variable must be created for each selector switch defined. EnigmaList1, EnigmaList2, etc
--
-- EnigmaStatus This holds the state of Enigma2 box and the current channel being viewed.Each value is separated by a "|"
-- f = not in standby. t = is in standby.
--
-- User variables are updated in a way that other that other scripts (Enigma-Scan) can be triggered if any of the uservariables changes.
-- If the EnigmaParams user variable is edited to start with a "*" this will trigger this script to update EnigmaList(n) with the
-- contents of the selector switches defined above.
--
-- The Enigma-Scan script which is trigged from this script will use the data in the user variables above to maintain the status
-- of the selector switches defined in EnigmaParams
-- This script require Lua sockets
-- Version 1.8
-- Setup Variables
commandArray = {}
Level = 0
http = require("socket.http")
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
LevelNames = ""
-- Set functions
function lines(str)
local t = {}
local function helper(line) table.insert(t, line) return "" end
helper((str:gsub("(.-)\r?\n", helper)))
return t
end
function get(data,name)
return data:match("<"..name..">(.-)</"..name..">")
end
function split(pString, pPattern)
local Table = {}
local fpat = "(.-)" .. pPattern
local last_end = 1
local s, e, cap = pString:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(Table,cap)
end
last_end = e+1
s, e, cap = pString:find(fpat, last_end)
end
if last_end <= #pString then
cap = pString:sub(last_end)
table.insert(Table, cap)
end
return Table
end
-- Start Program
-- Use function to move all params into tables
Vars = split(uservariables["EnigmaParams"],"|")
Status = split(uservariables["EnigmaStatus"],"|")
change = 0
On = Status[1]
Channel = Status[2]
-- Work out which table value holds the IP address. All params are shifted if the "*" params is used.
if Vars[1] == "*" then
IP = Vars[2]
else
IP = Vars[1]
end
print("Start Enigma Check")
-- Obtain powerstateof Enigma2 box
HttpPart = "http://" .. IP .. "/web/powerstate"
body = http.request(HttpPart)
-- If box is Off ( not in standby) script terminates
if body == nil then
print ("Enigma is Off")
return commandArray
end
row=lines(body)
Power = row[4]
Power = string.sub(Power, 1, 1)
On = string.sub (On, 1, 1)
-- check powerstate
if Power == On then
print "No Power state change"
else
print ("Powerstate changed " )
if Power == "f" then
change = 1
end
if Power == "t" then
change = 1
end
end
-- Get Current TV channel
HttpPart = "http://" .. IP .. "/web/subservices"
body = http.request(HttpPart)
if body == nil then
print ("Enigma is Off")
return commandArray
end
row=lines(body)
TChannel = get(row[5],"e2servicename")
print("EnigmaChannel is " .. TChannel)
-- Check Current Channel with Stored channel
if TChannel == Channel then
print "Channel not Changed"
else
print ("Channel changed to " .. TChannel)
change = 1
end
-- If user variables different from current trigger Json to change user variable . This will trigger lua scripts
if change == 1 then
TChannel=string.gsub(TChannel, " ", "%%20")
Param = (Power .. "|" .. TChannel)
HttpPart=("curl 'http://127.0.0.1:8080/json.htm?param=updateuservariable&type=command&vname=EnigmaStatus&vtype=2&vvalue=" .. Param .. "' &")
os.execute(HttpPart)
end
-- if "*" param used get SElector switch level lists and update user variables
if Vars[1] == "*" then
for i=4,#Vars do
print ("Switch List Update Switch " .. Vars[i])
HttpPart=("curl 'http://127.0.0.1:8080/json.htm?type=devices&rid=" .. Vars[i] .. "' &")
config=assert(io.popen(HttpPart))
Sw = config:read('*all')
config:close()
SwData = json:decode(Sw)
Level = SwData["result"][1]["LevelNames"]
Var = ("Variable:EnigmaList" .. (i-3))
commandArray[Var] = "*" .. (Vars[i] .. "|" .. string.sub(Level,5))
end
commandArray["Variable:EnigmaParams"] = string.sub(uservariables["EnigmaParams"], 3)
else
print ("No Switch List Update")
end
return commandArray
Code: Select all
-- Used in conjuction with Emigma. This progrom will kepp the nominated slector Paramsitches in sync with an
-- enigma 2 box.
-- This script uses uservariables updated by the enigna script. This script cannot be used in isolation.
-- Version 1.0
-- Functions
function split(pString, pPattern)
local Table = {}
local fpat = "(.-)" .. pPattern
local last_end = 1
local s, e, cap = pString:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(Table,cap)
end
last_end = e+1
s, e, cap = pString:find(fpat, last_end)
end
if last_end <= #pString then
cap = pString:sub(last_end)
table.insert(Table, cap)
end
return Table
end
-- Setup Variables
commandArray = {}
Level = 0
List = ""
TV={}
command = 0
i,v = 0
Channels=split(List,"|")
Vars = split(uservariables["EnigmaParams"],"|")
Status = split(uservariables["EnigmaStatus"], "|")
Power = Status[1]
CChannel = Status[2]
-- start program
print "Enigama Scan Start"
-- Create Channel List from all uservariables
for i,v in pairs(uservariables) do
if string.sub(i, 1, 10) == "EnigmaList" then
List = (List .. v .. "|")
end
end
Channels=split(List,"|")
-- set Power status
if string.sub(Power, 1, 1) == "t" then
commandArray[command]={["UpdateDevice"] = Vars[2] .. "|0|off"}
else
commandArray[command]={["UpdateDevice"] = Vars[2] .. "|1|on"}
end
-- Reset all selector switches to off
for i=2, #Vars do
TCh = Vars[i] .. "|2|0"
--keeps a note of how many switches to update
command = command + 1
-- Uses commandarray index to update multiple switches
commandArray[command]={["UpdateDevice"] = TCh}
end
-- Create Tv Table
--first array element is always a switch
Switch = string.sub(Channels[1], 2)
-- Setup varibles for loop
Level=10
--set first TV array element as outside main loop
TV[Channels[2]] = (Switch .. "|02|10")
-- Start loop from 3rd element as this must be the next channel
for j=3, #Channels do
Level = Level +10
if string.sub(Channels[j], 1, 1) == "*" then
Switch = string.sub(Channels[j], 2)
Level = 0
else
TV[Channels[j]] = (Switch .. "|02|" .. Level)
end
end
-- Test for valid tv Channel
if TV[CChannel] == nil then
print ("Channel " .. CChannel .. " not known")
return commandArray
else
print ("Update Switch " .. CChannel .. " With " .. TV[CChannel])
command = command + 1
commandArray[command]={["UpdateDevice"] = TV[CChannel]}
end
return commandArray
The Enigma script require a number of User variables to be created ( all strings) . Ensure you add the correct IdX values of the switches you created to the EnigmaParams user variable.
To populate the EnigmaList1,EnigmaList2, etc variables. Add *| at the beginning of the EnigmaPrams variable. If you make any changes to the selector switches again add the *| . Once the EnigmaList variables are updated the *| will be automatically removed.
The Enigma script also require Lua sockets see http://www.domoticz.com/wiki/Upload_ene ... et_library
I hope these scripts are useful to others