failed to call a uPNP action without parameters

I am on a rough ride learning how to write plugin. I have this Iphone tracker plugin kind of running but I struggle a lot with uPNP actions. I am basically trying to add a simple parameterless action called “ManualRefresh” in my service file

  <actionList>
    <action>
		<name>ManualRefresh</name>
    </action>

and do something dummy in the Implementation file, just for test

<actionList>
  
  	<action>
	 <serviceId>urn:upnp-org:serviceId:IPhoneLocator1</serviceId>
	 <name>ManualRefresh</name>
	  <run>
			luup.variable_set(service,"Location","toto",lul_device)
	  </run>
	</action>

I have tried to invoke it manually using the test lua code box like this

local lul_arguments = {}
lul_resultcode, lul_resultstring, lul_job, lul_returnarguments = luup.call_action("urn:upnp-org:serviceId:IPhoneLocator1",
                                                                                  "ManualRefresh", lul_arguments,
                                                                                  84)
return true

but all I manage to get is a error in the log file of vera which says

e[31;1mLuaInterface::CallFunction_Job device 84 function SIPhone_IPhoneLocator1_ManualRefresh_run failed attempt to call a nil valuee[0m <0x2fc41680>

I cannot figure out what is wrong. I have attached the plugin source code here in case somebody can pinpoint what I am doing wrong.

any thoughts from anybody ?

Try inlining a string literal instead of using the variable called “service”, which is defined in a lib.

Same result with this. I removed my ManualRefresh action and now NONE of my action are working any more. SetPresent action fails also
01 09/30/13 0:13:52.453 e[31;1mLuaInterface::CallFunction_Job device 83 function SIPhone_IPhoneLocator1_SetPresent_run failed attempt to call a nil valuee[0m <0x30145680>

<?xml version="1.0"?>
<implementation>
  <functions>

  </functions>

  <files>L_IPhone.lua,L_IPhoneJson.lua</files>
  <startup>initstatus</startup>
  <actionList>

	<action>
	 <serviceId>urn:upnp-org:serviceId:IPhoneLocator1</serviceId>
	 <name>SetPresent</name>
	  <run>
		luup.variable_set("urn:upnp-org:serviceId:IPhoneLocator1","Present",lul_settings.newPresentStatus,lul_device)
	  </run>
	</action>
	
    <action>
      <serviceId>urn:upnp-org:serviceId:IPhoneLocator1</serviceId>
      <name>GetPresent</name>
      <run>
        luup.variable_get("urn:upnp-org:serviceId:IPhoneLocator1", "Present", lul_device)
      </run>
    </action>
    <action>
      <serviceId>urn:upnp-org:serviceId:IPhoneLocator1</serviceId>
      <name>GetLocation</name>
      <run>
        luup.variable_get("urn:upnp-org:serviceId:IPhoneLocator1", "Location", lul_device)
      </run>
    </action>
	
    <action>
      <serviceId>urn:upnp-org:serviceId:IPhoneLocator1</serviceId>
      <name>GetDistance</name>
      <run>
        luup.variable_get("urn:upnp-org:serviceId:IPhoneLocator1", "Distance", lul_device)
      </run>
    </action>
	
   </actionList>
</implementation>
 

You don’t indicate how you’re calling this ACTION, so I’ll make some assumptions (below). To improve the accuracy of guesses, you’ll need to provide more of the log file, and be running in “Verbose” (debug) mode when those logs are captured. This will let folks see, for example, what parameters are being passed, and what values are coming with those parameters.

Guess 1…
You didn’t pass the parameter for the new status. When parameters aren’t passed, the [tt]lul_settings[/tt] variable is nil, so deref’ing it will give you a NPE issue.

Guess 2…
You passed it, but using incorrect case. Parameter names are case sensitive.

Side-note(s):

a) the Getter ACTIONS aren’t going to do anything meaningful, since MiOS defines no mechanism for them to return state.
I’d recommend you start this effort “small” and grow it, adding incrementally after validation that each piece works… it’ll definitely save you frustration in the long run…

You can also bench test some of the library functions completely outside of Vera, when you’re ready for that.

b) You’ll want an Isolated namespace, not “upnp-org” for your ServiceID’s.
The oldest plugins used to do that, but it was a bad habit. Newer plugins all put their code in a non “UPNP” namespace, since its’ not ours to pollute.

ok, thank you for the input, I will fix the service name.

for my problem, I will try to clarify what & how I test. I use this code in Test Lua code box

local lul_arguments = {}
lul_arguments["newPresentStatus"] = 1

lul_resultcode, 
lul_resultstring, 
lul_job, 
lul_returnarguments = 
luup.call_action(
"urn:upnp-org:serviceId:IPhoneLocator1",
"SetPresent", 
lul_arguments,
83)

return true

The log files ( in verbose mode ) shows:

[code]
08 09/30/13 0:50:58.205 JobHandler_LuaUPnP::HandleActionRequest argument Code=local lul_arguments = {}
lul_arguments[“newPresentStatus”] = 1

lul_resultcode,
lul_resultstring,
lul_job,
lul_returnarguments =
luup.call_action(
“urn:upnp-org:serviceId:IPhoneLocator1”,
“SetPresent”,
lul_arguments,
83)

return true <0x2f0d4680>
20 09/30/13 0:50:58.206 LuaInterface::StartEngine 0xbd0858 device 0 <0x2f0d4680>
10 09/30/13 0:50:58.206 sbrk JobHandler_LuaUPnP::HandleActionRequest from IP:255.255.255.255 pMem 0x132c000/20103168 diff: 9973760 <0x2f0d4680>
08 09/30/13 0:50:58.207 JobHandler_LuaUPnP::HandleActionRequest device: 83 service: urn:upnp-org:serviceId:IPhoneLocator1 action: e[36;1mSetPresente[0m <0x2f0d4680>
08 09/30/13 0:50:58.207 JobHandler_LuaUPnP::HandleActionRequest argument newPresentStatus=1 <0x2f0d4680>
01 09/30/13 0:50:58.207 e[31;1mLuaInterface::CallFunction_Job device 83 function SIPhone_IPhoneLocator1_SetPresent_run failed attempt to call a nil valuee[0m <0x2f0d4680>
10 09/30/13 0:50:58.210 UPnPCallbackEventHandler action RunLua request done pMem 0x132c000/20103168 diff: 9973760 took 0 <0x2f0d4680>[/code]

I am attaching my Implementation & Service file.
I tried boolean or string for “Present” variable without success.

Ok, so I tried a few different things, including nuking the TAB characters on some lines, in some files.

Eventually got it working. Problem appears to be the [tt][/tt] declaration that you’ve used.

When I simplify it down to:

<files>L_IPhone.lua</files>

Then the code appears to work correctly, at least in a test [tt]luup.call_action[/tt] block. In it’s original form (a CSV of two libs) then it fails. Since the first lib “requires” the second lib, it’ll load correctly anyhow.

Technically, you could avoid the declaration, and do a requires for both libs… which would also avoid the issue. Most other plugins do this, instead of the crazy MiOS “[tt][/tt]” tag, in order to support UI4 and UI5 (and be more Lua like)

PS: I also avoided calling the variables lul_*, in the test codeblock, but it shouldn’t make any difference.

My sincere and deep appreciation for your help. indeed it was it. it got me mad and finishing at 3am until I gave up and this morning I have the answer from you :slight_smile:

Regarding your other comment on chosing uPNP service name, is there some kind of rules / guidelines for that ?

You’re welcome.

The UPnP spec gives the general form:
?urn:domain-name:serviceId:serviceID?

And indicates that “upnp-org” is reserved for approved stuff, so most people have (in newer plugins) used either their own domain or the one of the company that the device is from.