Legacy Support > ThingWorx XMPP Edge MicroServer (EMS) Software > Edge Thing Configuration at the Device > Edge Enhanced Thing > Defining and Implementing Custom Services at the Edge
Defining and Implementing Custom Services at the Edge
Service Definition
A service definition provides the metadata for a service, defining the inputs and outputs of the server. A service definition is a separate entry in the local configuration than the service implementation. The names must match for the service to work as expected. An example of a service definitions follows below:
-- ------------------------------------------------------------------------------------------------
-- Service definitions provide metadata about the defined services. This metadata is used when
-- browsing services from the ThingWorx server. The name of the service definition must match
-- the name of the service it is defining. Each service definition can contain the following
-- fields, each with their own set of definition parameters:
-- input: Describes an input parameter to the service. At runtime, each input parameter can
-- be looked up inside of the 'data' table passed into the service. The valid input
-- fields are: name, baseType, description
-- output: A description of the output produced by the service. Valid fields are: baseType
-- and description.
-- description: A description of the service

input { name="p1", baseType="NUMBER", description="The first addend of the operation" },
input { name="p2", baseType="NUMBER", description="The second addend of the operation" },
output { baseType="NUMBER", description="The sum of the two parameters" },
description { "Add two numbers" }

input { name="p1", baseType="NUMBER", description="The number to subtract from" },
input { name="p2", baseType="NUMBER", description="The number to subtract from p1" },
output { baseType="NUMBER", description="The difference of the two parameters" },
description { "Subtract one number from another" }

output { baseType="NOTHING", description="" },
description { "Fire the ExampleEvent" }

output { baseType="DATETIME", description="" },
description { "Returns the current time" }

output { baseType="LOCATION", description="" },
description { "Returns the current location" }

input { name="date1", baseType="DATETIME", description="The time subtract from" },
input { name="date2", baseType="DATETIME", description="The time to subtract from date1" },
output { baseType="NUMBER", description="" },
description { "Returns the difference of the two times" }
Service Implementation in Lua Script
Once you have defined your own service, you can implement custom logic for the service using the Lua script engine. Lua is a full featured script language (see http://www.lua.org). In addition, there are Lua community add-ins that you can utilize to speed implementation (see http://www.lua.org/about.html). There is also a set of APIs that are specific to ThingWorx for use in Lua scripts built in the EMS installation to make creating custom scripts easier. Explanations and simple examples custom Lua scripts can be found below.
-- ------------------------------------------------------------------------------------------------
-- Services are defined as Lua functions. These can be executed remotely from the server and must
-- provide a valid response, via their return statement. The signature for the functions must be:
-- me: A table that refers to the Thing.
-- headers: A table of HTTP headers.
-- query: The query paramters from the HTTP request.
-- data: A Lua table containing the parameters to the service call.
-- A service must return the following values (in this order):
-- * A HTTP return code (200 for success)
-- * A table of HTTP response headers. This should contain a valid Content-Type header, typically
-- with a value of application/json. A default table can be easily generated by calling
-- tw_utils.RESP_HEADERS().
-- * The response date, in the form of a JSON string. This can be created from a Lua table using
-- json.encode, or tw_utils.encodeData().

services.Add = function(me, headers, query, data)
if not data.p1 or not data.p2 then
return 400, "You must provide the parameters p1 and p2"
return 200, data.p1 + data.p2

services.Subtract = function(me, headers, query, data)
if not data.p1 or not data.p2 then
return 400, "You must provide the parameters p1 and p2"
return 200, data.p1 - data.p2

services.FireExampleEvent = function(me, headers, query, data)
me.example_event_count = (me.example_event_count or 0) + 1
return server.fireEvent("ExampleEvent", {
label = me.name,
count = me.example_event_count,
time = os.time() * 1000

services.WhatTimeIsIt = function(me)
return 200, os.time() * 1000

services.WhereAmI = function(me)
return 200, { latitude = 40.033056, longitude = -75.627778, elevation = 338 }

services.DateDiff = function(me, headers, query, data)
if not data.date1 or not data.date2 then
return 400, "You must provide the parameters date1 and date2"

return 200, data.date1 - data.date2