zaphod Posted December 30, 2017 Share Posted December 30, 2017 Is there a C4: API command to get the current date/time or do you have to use Lua commands for this? There are various properties for some types of drivers - like power_delay and power_command_needed, etc. How do I access these properties from Lua code in the driver? How do I get my icons to show up? I have created the /www/icons folders in my c4z file like 20x20, 70x70, 90x90, 140x140, 400x400 but C4 is still using generic icons. Do the icon files have to have to have specific names as well, like icon.png? Do you have to specify the icons to be used somewhere in the XML file? Link to comment Share on other sites More sharing options...
msgreenf Posted December 30, 2017 Share Posted December 30, 2017 For icons: These are the icons that show in composer: <small image_source="c4z">icons/device_sm.png</small> <large image_source="c4z">icons/device_lg.png</large> for the icons for Navigator <capabilities> <navigator_display_option proxybindingid="5001"> <display_icons> <Icon height="140" width="140">controller://driver/nocontrol_laptop/icons/device/experience_140.png</Icon> <Icon height="130" width="120">controller://driver/nocontrol_laptop/icons/device/experience_130.png</Icon> <Icon height="120" width="120">controller://driver/nocontrol_laptop/icons/device/experience_120.png</Icon> <Icon height="110" width="110">controller://driver/nocontrol_laptop/icons/device/experience_110.png</Icon> <Icon height="100" width="100">controller://driver/nocontrol_laptop/icons/device/experience_100.png</Icon> <Icon height="90" width="90">controller://driver/nocontrol_laptop/icons/device/experience_90.png</Icon> <Icon height="80" width="80">controller://driver/nocontrol_laptop/icons/device/experience_80.png</Icon> <Icon height="70" width="70">controller://driver/nocontrol_laptop/icons/device/experience_70.png</Icon> <Icon height="60" width="60">controller://driver/nocontrol_laptop/icons/device/experience_60.png</Icon> <Icon height="50" width="50">controller://driver/nocontrol_laptop/icons/device/experience_50.png</Icon> <Icon height="40" width="40">controller://driver/nocontrol_laptop/icons/device/experience_40.png</Icon> <Icon height="30" width="30">controller://driver/nocontrol_laptop/icons/device/experience_30.png</Icon> <Icon height="20" width="20">controller://driver/nocontrol_laptop/icons/device/experience_20.png</Icon> </display_icons> </navigator_display_option> </capabilities> obviously you would update the name and paths Link to comment Share on other sites More sharing options...
zaphod Posted December 30, 2017 Author Share Posted December 30, 2017 What exactly will I have to replace? Does "controller" get changed to the actual IP of the controller? I am guessing not For example, here is the complete path to my 140x140 icon is: /mnt/internal/c4z/SageExtender/www/icons/140x140/sage400.png <Icon height="140" width="140">controller://driver/SageExtender/icons/140x140/sage140.png</Icon> or <Icon height="140" width="140">controller://driver/SageExtender/www/icons/140x140/sage400.png</Icon> or even something else. And where do you enter this in DriverEditor 3.01? Or do you just paste it directly into the XML file by editing driver.xml within the c4z zip file? If it is the latter is there an easy way to edit files within a zip archive rather than unzipping and then rezipping? Link to comment Share on other sites More sharing options...
msgreenf Posted December 30, 2017 Share Posted December 30, 2017 What exactly will I have to replace? Does "controller" get changed to the actual IP of the controller? I am guessing not For example, here is the complete path to my 140x140 icon is: /mnt/internal/c4z/SageExtender/www/icons/140x140/sage400.pngcontroller://driver/SageExtender/icons/140x140/sage140.png orcontroller://driver/SageExtender/www/icons/140x140/sage400.png or even something else. And where do you enter this in DriverEditor 3.01? Or do you just paste it directly into the XML file by editing driver.xml within the c4z zip file? If it is the latter is there an easy way to edit files within a zip archive rather than unzipping and then rezipping? I don't use driver editor. I use vs code and the command line to buildcontroller://driver/SageExtender/icons/140x140/sage140.pngSent from my Pixel XL using Tapatalk Link to comment Share on other sites More sharing options...
zaphod Posted December 31, 2017 Author Share Posted December 31, 2017 Ok thanks. So you can just use on folder for all of the icons rather than separate ones? That is much easier! One other thing that isn't working for me is Actions. Here is the XML code which is within the config section: <actions> <action> <name>Test Action</name> <command>test1</command> </action> <action> <name>Test Action2</name> <command>test2</command> </action> </actions> And I have the following code within my lua file: function LUA_ACTION.test1(str) --Required for Actions screen print ("Action1 Testing Connection"..str) g_URLPacket = url1.."/sage/Home" C4:urlGet(g_URLPacket) end function LUA_ACTION.test2(str) print ("Action2 Testing Connection"..str) g_URLPacket = url1.."/sage/Home" C4:urlGet(g_URLPacket) end function LUA_ACTION.test1(str) --Required for Actions screen print ("Action1 Testing Connection"..str) g_URLPacket = url1.."/sage/Home" C4:urlGet(g_URLPacket) end function LUA_ACTION.test2(str) print ("Action2 Testing Connection"..str) g_URLPacket = url1.."/sage/Home" C4:urlGet(g_URLPacket) end But nothing happens - I never even get anything from the print command in the Lua window but it seems like C4 is getting the action, just not acting on it as nothing prints out to the Lua window. If I look in the driver-event log files I do see: 2017-12-31 13:19:03 -0500 home-controller-hc250-000FFF163637 [16662] INFO: Executing command (LUA_ACTION) on driver SageTV(215) Link to comment Share on other sites More sharing options...
msgreenf Posted December 31, 2017 Share Posted December 31, 2017 Do you have this bit of code in there? --[[ EX_CMD.LUA_ACTION Function called for any actions executed by the user from the Actions Tab in Composer. --]] function EX_CMD.LUA_ACTION(tParams) if tParams ~= nil then for cmd,cmdv in pairs(tParams) do if cmd == "ACTION" then if (LUA_ACTION[cmdv] ~= nil) then LUA_ACTION[cmdv]() else Dbg:Alert("Undefined Action") Dbg:Alert("Key: " .. cmd .. " Value: " .. cmdv) end else Dbg:Alert("Undefined Command") Dbg:Alert("Key: " .. cmd .. " Value: " .. cmdv) end end end end Link to comment Share on other sites More sharing options...
zaphod Posted December 31, 2017 Author Share Posted December 31, 2017 No, I didn't have that. What is that for? Link to comment Share on other sites More sharing options...
zaphod Posted January 1, 2018 Author Share Posted January 1, 2018 I have my icons showing up very nicely in Navigator but still no luck for Composer. I have tried stopping and starting Composer and I can verify that the files exist as: /mnt/internal/c4z/SageExtender/www/icons/device_sm.png and/mnt/internal/c4z/SageExtender/www/icons/device_lg.png. These are 16x16 and 32x32 png files created in paint.net. I notice that these files also seem to be defined in a proxy line. So I have added a line like this: <proxies> <proxy proxybindingid="5001" name="SageTV" image_source="c4z" small_image="icons/device_sm.png" large_image="icons/device_lg.png">media_player</proxy> </proxies> But still no luck. Does the name field here have significance? Is there anything else that you have to do to get Composer to refresh the icons it uses? Link to comment Share on other sites More sharing options...
zaphod Posted January 1, 2018 Author Share Posted January 1, 2018 I still can't get actions to work at all. Here is the Actions part from my XML file. <actions> <action> <name>Test Action</name> <command>testit</command> </action> </actions> And here is the code from my Lua file - I don't know if all of this is needed: --Function called for any actions executed by the user from the Actions Tab in Composer. function EX_CMD.LUA_ACTION(tParams) if tParams ~= nil then for cmd,cmdv in pairs(tParams) do if cmd == "ACTION" then if (LUA_ACTION[cmdv] ~= nil) then LUA_ACTION[cmdv]() else --Dbg:Alert("Undefined Action") print("Undefined Action") -- all print items were changed from Dbg:Alert as above print("Key: " .. cmd .. " Value: " .. cmdv) end else print("Undefined Command") print("Key: " .. cmd .. " Value: " .. cmdv) end end end end function LUA_ACTION.testit(str) --Required for Actions screen print ("Action1 Testing Connection"..str) TestURL() end And nothing happens when I push my actions button - although the Sage driver_event log is obviously seeing something as I do see this entry, But no code appears to be executed 2017-12-31 22:15:10 -0500 home-controller-hc250-000FFF163637 [2020] INFO: Executing command (LUA_ACTION) on driver SageTV(215) Link to comment Share on other sites More sharing options...
RyanE Posted January 1, 2018 Share Posted January 1, 2018 What does your ExecuteCommand function look like? Ultimately, all commands and actions go through ExecuteCommand. The templates and sample code go through, and based on the name of the command, fire the relevant EX_CMD or LUA_ACTION. For most drivers, mine are much simpler than all that: function ExecuteCommand(strCmd, tParams) tParams = tParams or {} dbg("ExecuteCommand: " .. strCmd) for k,v in pairs(tParams) do dbg(k,v) end if (strCmd == "LUA_ACTION") then local action = tParams["ACTION"] or "" if (action == "SETUP_ACCOUNT") then -- set up account code goes here... end end if (strCmd == "Set Home Status") or (strCmd == "Set All Home Status") then local status = tParams["Status"] or "" if (status == "") then return end -- do Set Home Status stuff here... end end RyanE Link to comment Share on other sites More sharing options...
zaphod Posted January 1, 2018 Author Share Posted January 1, 2018 I don't have an ExecuteCommand function so I guess that is the issue. I just pasted in your code into my Lua file (other than changing the dbg to a print in line 4) but it doesn't help at all - as I still don't get any output printed to the Lua window, nor do any actions occur. So do you need all three functions - a ExecuteCommand, a LUA_ACTION and a EX.CMD_LUA_ACTION? What is the process flow when a LUA_ACTION occurs. I now it is actually seeing a function from the driver event log. Link to comment Share on other sites More sharing options...
wappinghigh Posted January 1, 2018 Share Posted January 1, 2018 ^ I admire you Z you are awesome. W Link to comment Share on other sites More sharing options...
RyanE Posted January 1, 2018 Share Posted January 1, 2018 If the ExecuteCommand you added in (mine) from above isn't showing anything (assuming you have a 'dbg' function), then there is a different definition for the ExecuteCommand defined somewhere else in your code, that's writing over mine. If you're using a template file, it likely includes other .lua files, which is where it could be defined. If you post the whole file, we could see what's going on. RyanE Link to comment Share on other sites More sharing options...
zaphod Posted January 1, 2018 Author Share Posted January 1, 2018 Ok, here is all of the Lua code. Do you need any of the XML file as well? Do I need some XML dealing with Commands? Maybe that is what I am missing? I have an <actions> section in my XML but no <commands> section. If I do need this then how do you set it up? Does the name have to tie back exactly to the command name in the Action? --[[ 12/30/2017/ 13:00 Add URL test to verify connection. Tests for good URL, authentication and makes sure that context/extender is alive. ]] CMDS = { PLAY = "Play", PAUSE = "Pause", STOP = "Stop", OPEN_CLOSE = "Stop%2FEject", SKIP_FWD = "Right%2FSkip+Fwd", SKIP_FWD2 = "Skip%20Fwd%20%232", SKIP_REV = "Skip+Bkwd%2FPage+Left", SCAN_FWD = "Skip%20Fwd%20%232", SCAN_REV = "Skip%20Bkwd%20%232", RECORD = "Record", ENTER = "Select", UP = "Up", GUIDE = "Guide", DOWN = "Down", LEFT = "Left", RIGHT = "Right", MENU = "Home", START = "Power+On", BACK = "Back", RECALL = "Previous+Channel", CANCEL = "Back", INFO = "Info", WINDOW_HOME = "Home", WINDOW_MUSIC = "Music+Jukebox", WINDOW_VIDEOS = "Video+Library", MUTE_TOGGLE = "Mute", PVR = "Options", PAGE_UP = "Channel+Up%2FPage+Up", PAGE_DOWN = "Channel+Down%2FPage+Down", NUMBER_0 = "Num+0", NUMBER_1 = "Num+1", NUMBER_2 = "Num+2", NUMBER_3 = "Num+3", NUMBER_4 = "Num+4", NUMBER_5 = "Num+5", NUMBER_6 = "Num+6", NUMBER_7 = "Num+7", NUMBER_8 = "Num+8", NUMBER_9 = "Num+9", PROGRAM_A = "Delete", PROGRAM_B = "Guide", PROGRAM_C = "Power", PROGRAM_D = "Options", } ip = C4:GetBindingAddress(6001) serverport = Properties["Web Server Port"] mac = Properties["Extender MACID"] pass = Properties["Password"] user = Properties["User"] url1 = "http://" .. user .. ":" .. pass .."@"..ip ..":".. serverport g_Receivebuffer="" C4:CreateNetworkConnection (6100, Properties["Extender IP Address"]) -- this is for telnet control to extender --=-=-=-=-=-=-=-=- FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=- function ReceivedFromNetwork(idBinding, nPort, strData) print ("Reciving from Network on Binding and Port"..idBinding .. nPort..strData) g_Receivebuffer=g_Receivebuffer .. strData end function PowerOffExtender() C4:SendToProxy(5001, "OFF","") g_URLPacket = url1 .. url2 .. "Stop" C4:urlGet(g_URLPacket) --send Sage a Stop command if Properties["Send Power Commands"] == "True" then C4:NetConnect(6100,23) local t = C4:SetTimer(2000, function(timer) --this is a way to pass for 2000 ms C4:SendToNetwork(6100, 23, "root\nkillall miniclient\nexit\n") end) end end function PowerOnExtender() InitializeURL() if Properties["Send Power Commands"] == "True" then C4:NetConnect(6100,23) local t = C4:SetTimer(2000, function(timer) --this is a way to pass for 2000 ms C4:SendToNetwork(6100, 23, "root\nkillall waitpower\nexit\n") end) end end function ReceivedFromProxy(idBinding, strCommand, tParams) if Properties["Debug Mode"] == "True" then print("ReceivedFromProxy [" .. idBinding .. "] : " .. strCommand) if (tParams ~= nil) then for ParamName, ParamValue in pairs(tParams) do print(ParamName, ParamValue) end end end cmd = CMDS[strCommand] if (cmd ~= nill) then if Properties["Debug Mode"] == "True" then print( "Send to Device: " .. cmd) end g_URLPacket = url1 .. url2 .. cmd if Properties["Debug Mode"] == "True" then print("URL is: " .. g_URLPacket) end C4:urlGet(g_URLPacket) else print ("going to Command Interpreter with command: "..strCommand) CommandInterpreter(strCommand, tParams) end end function TestURL() g_URLPacket = url1..url2.."Home" if Properties["Debug Mode"] == "True" then print("Sending... g_URLPacket: " .. g_URLPacket) end C4:urlGet(g_URLPacket, {}, false, function(ticketId, strData, responseCode, tHeaders, strError) if (strError == nil) then if string.find(strData,"UNAUTHORIZED") then print "C4:urlGet() failed as UNAUTHORIZED was returned - check username and password" else if string.find(strData,"not connected") then print("C4:urlGet() succeeded but the extender or clients is not connected " ) else print("C4:urlGet() succeeded! " ) end end else print("C4:urlGet() failed: " .. strError) end end) end function OnPropertyChanged(strProperty) InitializeURL() print ("Property "..strProperty.." has changed to "..Properties[strProperty]) print ("Updating URL info") print ("New URL is: "..url1..url2) TestURL() end function InitializeURL() ip = C4:GetBindingAddress(6001) serverport = Properties["Web Server Port"] mac = Properties["Extender MACID"] pass = Properties["Password"] user = Properties["User"] url1 = "http://" .. user .. ":" .. pass .."@"..ip ..":".. serverport url2 = "/sage/SageCommand?context=" .. mac .."&command=" end function OnDriverLateInit() InitializeURL() end function CommandInterpreter(strCommand, tParams) print (strCommand) if (strCommand == "ON") then print ("Turning the SageTV ON") --Put command here to turn on extender PowerOnExtender() else if (strCommand == "OFF") then print ("Turning the SageTV OFF") PowerOffExtender() --Put command here to turn off extender end end end --Function called for any actions executed by the user from the Actions Tab in Composer. function EX_CMD.LUA_ACTION(tParams) if tParams ~= nil then for cmd,cmdv in pairs(tParams) do if cmd == "ACTION" then if (LUA_ACTION[cmdv] ~= nil) then LUA_ACTION[cmdv]() else --Dbg:Alert("Undefined Action") print("Undefined Action") -- all print items were changed from Dbg:Alert as above print("Key: " .. cmd .. " Value: " .. cmdv) end else print("Undefined Command") print("Key: " .. cmd .. " Value: " .. cmdv) end end end end function LUA_ACTION.testit() --Required for Actions screen print ("Action1 Testing Connection") TestURL() end function ExecuteCommand(strCmd, tParams) tParams = tParams or {} print("ExecuteCommand: " .. strCmd) for k,v in pairs(tParams) do dbg(k,v) end if (strCmd == "LUA_ACTION") then local action = tParams["ACTION"] or "" if (action == "SETUP_ACCOUNT") then -- set up account code goes here... end end if (strCmd == "Set Home Status") or (strCmd == "Set All Home Status") then local status = tParams["Status"] or "" if (status == "") then return end -- do Set Home Status stuff here... end end -- INIT -- Link to comment Share on other sites More sharing options...
RyanE Posted January 1, 2018 Share Posted January 1, 2018 Looks to me like you're not seeing anything when ExecuteCommand executes, since there's no 'dbg' function, which is what is being called in there to print out the debug statements. If you add this line: dbg = print You should at least see the ExecuteCommand being called. Without seeing your XML, it's not possible to know what actions and commands you have defined, to see what you'd need to code in your ExecuteCommand function. Personally, on such a simple driver, I would *just* parse things in the ExecuteCommand, not have that then call EX_CMD and LUA_ACTION. RyanE Link to comment Share on other sites More sharing options...
zaphod Posted January 1, 2018 Author Share Posted January 1, 2018 I don't have any Commands in my XML - is that the issue? Link to comment Share on other sites More sharing options...
RyanE Posted January 1, 2018 Share Posted January 1, 2018 ExecuteCommand only gets called for 2 things: Actions the user triggers in Composer, on the Actions tab, which are defined in your XML. Commands that are triggered by Composer programming, which are also defined in your XML. If you have neither of those defined, your ExecuteCommand won't ever get fired. RyanE Link to comment Share on other sites More sharing options...
zaphod Posted January 1, 2018 Author Share Posted January 1, 2018 I do have an Action defined in the XML file which is shown in some of the code posted above. But I don't have any <command> entries in the XML. Link to comment Share on other sites More sharing options...
Rexabyte Posted January 3, 2018 Share Posted January 3, 2018 ExecuteCommand(strCommand, tParams) takes both commands from the <commands> portion of the XML and the <actions> portion of the XML. The only difference is that the strCommand portion will be "LUA_ACTION" and the tParams table will contain an "ACTION" key when you receive an action. A command will come directly into 'strCommand' and its parameters will reside in the table. Examples: Command: <command> <name>Synthesize Text</name> <description>Synthesize text - PARAM1</description> <params> <param> <name>Text</name> <type>STRING</type> <readonly>False</readonly> <default /> </param> </params> </command> -- The above would send you this ExecuteCommand("Synthesize Text", {Text = "This is my text"}) Action: <action> <name>Update Now</name> <command>UPDATE</command> </action> -- The above would send you this ExecuteCommand("LUA_ACTION", {ACTION="UPDATE"}) This is what it looks like in my Clare driver, this is only worrying about <actions> and not <commands>. <actions> <action> <name>Toggle DND</name> <command>TOGGLE_DND</command> </action> <action> <name>Refresh Announcements</name> <command>REFRESH_ANNOUNCEMENTS</command> </action> <action> <name>Configure Sub Stream</name> <command>CONFIGURE_SUB_STREAM</command> </action> </actions> function class.ExecuteCommand(strCommand, tParams) Logger.Trace("Driver.ExecuteCommand[" .. strCommand .. "]") Logger.Debug(tParams) if (strCommand == "LUA_ACTION") then local action = tParams["ACTION"] if (action == "CONFIGURE_SUB_STREAM") then class.clare:configure() elseif (action == "REFRESH_ANNOUNCEMENTS") then class.RefreshAnnouncements() elseif (action == "TOGGLE_DND") then class.isDND:set(not class.isDND:get()) end end end Link to comment Share on other sites More sharing options...
zaphod Posted January 4, 2018 Author Share Posted January 4, 2018 I must be a total idiot as I still can't get anything to fire on Actions. Here is what I have for actions under the <config> section of my XML: <actions> <action> <name>Test Action</name> <command>TESTIT</command> </action> </actions> And here is the Lua code (a slight variation on what was posted above): function class.ExecuteCommand(strCmd, tParams) Logger.Trace("Driver.ExecuteCommand[" .. strCommand .. "]") Logger.Debug(tParams) if (strCmd == "LUA_ACTION") then local action = tParams["ACTION"] if (action == "TESTIT") then print ("Action1 Testing Connection!!!!!!!!!!!!!!") TestURL() end end end So shouldn't it print Action1 Testing Connection!!!!!!!!!!!!!! to the window and run the TestURL function when I click on Action "Test Action"? I do see the following in the driver_event.log file: "2018-01-03 23:29:59 -0500 home-controller-hc250-000FFF163637 [2020] INFO: Executing command (LUA_ACTION) on driver SageTV(215)" So the action is registering, it just doesn't appear to be triggering any commands to execute. Link to comment Share on other sites More sharing options...
RyanE Posted January 4, 2018 Share Posted January 4, 2018 what is class? ExecuteCommand is the name of the function Director will call in a DriverWorks driver. It shouldn't be declared in any class. TheWizard must do some handling where he calls his class.ExecuteCommand when Director calls ExecuteCommand. Remove the 'class.' in front of your ExecuteCommand declaration, and it should work. Just to ensure your print statements will work, I'd also not use a Logger.Trace class to print. Just change those to print('blah'). RyanE Link to comment Share on other sites More sharing options...
Rexabyte Posted January 4, 2018 Share Posted January 4, 2018 function ExecuteCommand(strCmd, tParams) print("ExecuteCommand") if (strCmd == "LUA_ACTION") then print("Executing an action") local action = tParams["ACTION"] if (action == "TESTIT") then print ("Action1 Testing Connection!!!!!!!!!!!!!!") TestURL() end end end Try the above. The "Logger" and "class" objects posted previously are part of some other stuff which are not relevant. Logger is my own logging utility and Ryan assumed correctly that the function I posted was being called by the global "ExecuteCommand" Link to comment Share on other sites More sharing options...
zaphod Posted January 5, 2018 Author Share Posted January 5, 2018 So I finally got this working but I had to put the ExecuteCommand function at the top of the functions area of my Lua file. All I did was cut it from the bottom and paste it in the top and it worked. Maybe some other character or something was causing problems. Link to comment Share on other sites More sharing options...
msgreenf Posted January 5, 2018 Share Posted January 5, 2018 5 hours ago, zaphod said: So I finally got this working but I had to put the ExecuteCommand function at the top of the functions area of my Lua file. All I did was cut it from the bottom and paste it in the top and it worked. Maybe some other character or something was causing problems. that means you have either a duplicate function or you had ending of functions wrong Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.