State Variables and Service xml

In UI7, going to Devices…(expand a device)… Control…advanced…

There is a section that shows “variables.”

  1. I assume these are the state variables for all the services tied to this device. Is that correct?
  2. I can cause a variable name and value to appear hear by executing “luup.variable_set”.
  3. When state variables are defined within the S_[device].xml file, they don’t seem to automatically be visible here. Do the variables only appear once they are “set”? that is, if I want a variable to appear, but with nothing defined, do I need to at least set the variable to nil using luup.variable_set?

The S_XXX.xml defines the UPnP specification for the device. Does not actually create the variables.
In Vera a call to luup.variable_set creates the variables.

Often plugins will create all of their Variables if they are not currently defined.

You can create a variable that is not in the S_XXX.xml file … it just means it’s description is not publicly available.

Understood. Thanks for the explanation.

My next hurdle:

I am successfully calling the “run” code from the UI of the child device. (I flip the ‘on/off’ multi-state button in the child device GUI, and it starts running code in my parent implementation file as designed.)

Only, I don’t know how to reference the set variable from the java script.

In my case, the javascript command has parameters with the name “newLoadLevelTarget” and it sets the value to “100”.

I was (apaprently wrongly) assuming that the Vera would update the state variable “newLoadLevelTarget” when the UI / java script was executed, so then I would read that variable from the implementation lua. How do I read the value of “newLoadLevelTarget” that was set by the javascript?

Actually you call methods on your device with device actions (Also specified in the S_XXXX.xml) these MUST be defined.

Actions, such as turn on a light, changes a state variable, but bot because of the definition in the S_XXXX.xml file.
The argument is supplied to the call to luup.call_actions … your implementation needs to extract this value and set the appropriate state variable.

Actions have two forms:
RUN and JOB
A RUN action should execute quickly (i.e. no HTTP or Netork or Z-Wave request internal to it).
A JOB Action queues the request to the Plugin and the caller returns immediately why the request works in the background.

There are lots of postings that show how to call device actions from LUA or Javascript.
In all cases the definitions are found in the devices corresponding S_XXXX.xml file.

I’m still not quite sure what I’m missing…I really appreciate your patience. I’m sure it’s some silly concept that I’m just not getting. I’m going to be painfully verbose so bear with me.

Physically…For the record, my implementation is similar to the somfy “walkthough.” I have a parent device that is in fact a serial controller. I just need to send it text commands (and will be receiving data…but that’s for another time.). Not that it matters, but the serial device communicates with the actual lighting devices over RF.

The Vera implementation:

My parent device I intend to do all the interacting with the physical serial device. The Implementation file for the parent is defined to “handle children”. I have a “SetLoadLevelTarget” action defined in the parent implementation file. This action includes a (may make it a ) that ultimately sends text to the serial device. (luup.io.write).

The child devices are the standard DimmableLights supplied with Vera.

When the on/off toggle is clicked on the DimmableLight UI, It executes action “SetLoadLevelTarget”, with a single parameter “newLoadLevelTarget”.

I have verified that the code in my “SetLoadLevelTarget” action in the parent implementation file is in fact running when the on/off button is clicked. What I do not know how to do is get the value of “newLoadLevelTarget” that is set in the javascript…so I can use that value when I build the i/o string to my serial device.

Thanks again for your patience!

EDIT: I believe I need to make use of “lul_settings” ?

In your Implementation file for the “SetLoadLevelTarget”
The function is called with two argument …

  1. lul_device - The DeviceID (In this case the DeviceID of the child)
  2. lul_settings a table with all of the arguments that were sent to the luup.call_action function.
    Note: If this is called remotely from JavaScript … the html reader in the LuaUPnP program unpacks all of the Arguments and creates the table of arguments.
    If you call this from lua … you pass the table of arguments.
 <actionList>
    <action>
      <name>SetLoadLevelTarget</name>
      <serviceId>urn:Your.ServiceID</serviceId>
      <run>
           luup.log("DeviceID:" .. lul_device)
           luup.log("Target:" .. lul_settings.newLoadLevelTarget)
      </run>
    </action>

Another comment …
Since you said you you are ultimately going to send data to a RF controller.
If there is any chance that that could BLOCK you should do a JOB instead of a RUN

<actionList>
    <action>
      <name>SetLoadLevelTarget</name>
      <serviceId>urn:Your.ServiceID</serviceId>
      <job>
           luup.log("DeviceID:" .. lul_device)
           luup.log("Target:" .. lul_settings.newLoadLevelTarget)
           return 4, nil
      </job>
    </action>

Note the extra return statement.

So this is what is diving me batty. I had tried essentially exactly that earlier and not get results. Here’s another go at it:

Here’s my code in the parent implementation file:

[code]

urn:upnp-org:serviceId:Dimming1
SetLoadLevelTarget

luup.log("Attempting to manipulate lighting group: " … luup.devices[lul_device].id)
luup.log(“Parameter newLoadLevelTarget:” … tostring(lul_settings.newLoadLevelTarget))
return 4, nil

		</job>
	</action>
</actionList>[/code]

And here’s the output after clicking on the Switch in the UI…newLoadLevelTarget is nil… (The lighting group ID is correct):

50 12/08/14 23:02:28.208 luup_log:18: Attempting to manipulate lighting group: 1280 <0x2acc7000> 50 12/08/14 23:02:28.208 luup_log:18: Parameter newLoadLevelTarget:nil <0x2acc7000>

Any ideas? (And thanks for the tips…I probably will BLOCK on certain commands when I get to the point of reading output from the device. Been reading up on “Incoming”…)

First things first though…I just want to turn on my light. :slight_smile:

Is it NewLoadLevelTarget or newLoadLevelTarget or newLoadlevelTarget?

Perhaps print out the entire table’s keys and values into the Luup log and make sure that you aren’t being bitten by UPnP’s weird capitalization.

Edit: curse you, autocorrect, for trying to fix my deliberate lowercase.

Here is a handy debug function I have when I have no idea what’s going on.
It will dump a LUA variable that’s a function, string, table, number … )

function dump(o, levels, nofunc)
   local nlevels
   if (levels) then
      nlevels = levels - 1
   end
   local ot = type(o)
   if ot == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         local r
         if (levels) then
            if ((levels > 0) or (type(v) ~= "table"))  then
               r = dump(v, nlevels, nofunc)
            else
               r = "*" .. type(v) .. "*"
            end
         else
            r = dump(v, levels, nofunc)
         end
         s = s .. '['..k..'] = ' .. r .. ','
      end
      return s .. '} '
   else
      if (nofunc and (ot == 'function')) then
         return("*f")
      else
         return tostring(o)
      end
   end
end

You can use it as:
luup.log(dump(lul_settings))

Drat!! It is in fact newLoadlevelTarget…and I am referencing newLoadLevelTarget .

So for whatever reason, Vera decided to be inconsistent with capitalization with its Dimmable Light device…sigh. Depending on the action, the parameter is different:

Example:
Action: StartRampToLevel
Parameter: newLoadLevelTarget

Action: SetLoadLevelTarget
Parameter: newLoadlevelTarget

Maddening…but lesson learned!

Thanks to both of you RichardTSchaefer and futzle for pointing me in the right direction,a ndfor the useful debugging function!

I don’t have time to update and test right now, but I will report back later.