When product.lua is called


#1

I am trying to adapt the simple_graph example code from the exosite/murano_examples repository. I have a device which sends sensor data every 10s, and I want a public api endpoint to be able to return a JSON object containing just the most recent data that has been sent when queried. I tried to do this by modifying api_routes.lua as well as product.lua script located in the service_handlers folder, but I am confused about when this script is actually run, as it seems that the data argument that is passed in only contains some values and not others when each update is made, and it even entirely misses some updates. When is this script actually called, and is there a better way to accomplish this?

Thanks,

David Baerg


#2

@dboccammd,

Great question, thanks for posting!

The Lua scripts are executed by Murano in reaction of a system event. This could be when new data received for a device, or when a call hits one of your custom API routes. Since you wanted to expose a public API, the routes path seems like the direction to go.

Consider the following Lua code from our Home Automation example.

-- get details about a particular lightbulb
local sn = tostring(request.parameters.sn)
local user = currentUser(request)
if user ~= nil then
  local isowner = User.hasUserRoleParam({
    id = user.id, role_id = "owner", parameter_name = "sn", parameter_value = sn
  })
  local isguest = User.hasUserRoleParam({
    id = user.id, role_id = "guest", parameter_name = "sn", parameter_value = sn
  })
  if isowner == 'OK' or isguest == 'OK' then
    return kv_read(sn)
  else
    http_error(403, response)
  end
else
  http_error(403, response)
end

This code is attached to the [GET] /lightbulb/{sn} APi route. The code captures the request, checks the user’s permissions, and then returns either the lightbulb’s data or a 403 error. It you wanted this to be public, and drop the user system complication, you could pare down this script to only a few lines:

local sn = tostring(request.parameters.sn)
if sn ~= nil then
    return kv_read(sn)
else
    http_error(400, response)
end

I haven’t tested this code, so feel free to give it a shot. You should be able create a custom route for your solution, and modify this code to do what you want.

Additional documentation on Murano scripting can be found here: http://docs.exosite.com/murano/scripting/

Let me know if you have trouble – I am happy to help,
-Martin


#3

I don’t see how I would adapt this to my situation. I understand that the scripts in the service_handlers folder are run in response to events, but essentially what I’m asking is what exact event triggers the product.lua script being called, and if there exists some other event that receives every updated field every single time. Because the important thing is that I don’t want to lose any updates that are sent to the server.

For instance, how would I go about handling the datapoint (http://docs.exosite.com/murano/services/device/#datapoint) event? Is this the event I’m looking for? I read the documentation, but it’s not clear to me where in general to put code that gets called when a particular event happens.

Additionally, is there any way I can print out debug information from a lua script somewhere?


#4

Hi David,

Sorry for the delay. The product is very new to me too, and I wanted to ensure that I understood Murano deeply enough to answer you questions adequately. I mentioned the custom API route to you because earlier you had said:

The way product.lua works is that it is the single registered event handler for the (http://docs.exosite.com/murano/services/device/#datapoint) event. Murano supports defining a single event handler written lua to handle each new datapoint publication. The answer to, “when is product.lua called?” is “each time a device that belongs to a product that you have associate with your solution writes new data.”

I read the documentation, but it’s not clear to me where in general to put code that gets called when a particular event happens.

In your Solutionfile.json for a given solution(example or custom), the system automatically uploads the Lua code referenced by the following keys as the datapoint event handler:

  "event_handler": {
    "device": {
      "datapoint": "service_handlers/product.lua"
    }
  }

In this case, Murano would look for the Lua script called ‘product.lua’ in the service_handlers directory in the repository of the deployed solution.

You can edit your datapoint handler either by modifying the script locally and redeploying your solution, or by editing the Lua code already in your browser:

Hopefully that should clarify some things regarding product.lua.

Additionally, is there any way I can print out debug information from a lua script somewhere?

I am still looking into this, and will post again as soon as I know more about debugging in Murano.

-Martin