Exploring an EMS / LSR configuration using REST APIs
In this blog I will be inspecting the setup below, using the REST APIs exposed by the different components (log-analysis-free guaranteed).

The components are started in stages, and I will do some exploration between each stages :
- EMS only
- EMS + LSR 1
- EMS + LSR 1 + LSR 2
The REST APIs
- Edge MicroServer (EMS) REST API
- This API is very similar to the ThingWorx platform REST API, see REST APIs Supported by WS EMS for specificity.
- I will be monitoring the EMS using the LocalEms virtual Thing (EMS only)
- ThingWorx Platform REST API
- This is the well known ThingWorx Core REST API - see REST API Core Concepts
- I will be monitoring the EMS, from the platform, using an EMSGateway thing.
- The EMSGateway exposes on the platform some of the LocalEms services (like GetEdgeThings).
- I'm also inspecting the remote properties / services / events exposed on the things using the RemoteThing::GetRemoteMetadata service.
- Lua Script Resource (LSR) REST API
- This API largely differs from the ones above, the API documentation is served by the LSR itself (e.g. http://localhost:8001/)

- I will use it to list the scripts loaded by the LSR process.
Configuration
See above diagram - Platform is listening on port 8084, no encryption, EMS and LSRs on the same host...
- Platform configuration : for each edge thing, a corresponding remote thing was manually created on the platform
- EMSGateway1 as a EMSGateway Thing Template
- EMSOnlyThing as a RemoteThingWithFileTransfer
- LUAThing2 as a RemoteThing
- LUAThing1 as a RemoteThing
- LUAOnlyThing as a RemoteThing
- EMS configuration : /etc/config.json - listening on default port 8000
{
"ws_servers": [{
"host": "tws74neo",
"port": 8084
}
],
"appKey": "xxxxxx-5417-4248-bc01-yyyyyyy",
"logger": {
"level": "TRACE"
},
"ws_connection": {
"encryption": "none"
},
"auto_bind": [{
"name": "EMSGateway1",
"gateway": true
}, {
"name": "EMSOnlyThing",
"gateway": false
}, {
"name": "LUAThing2",
"host": "localhost",
"port": 8002,
"gateway": false
}, {
"name": "LUAThing1",
"gateway": false
}
],
"file": {
"virtual_dirs": [{
"emsrepository": "E:\\ptc\\ThingWorx\\EMS-5-3-2\\repositories\\data"
}
],
"staging_dir": "E:\\ptc\\ThingWorx\\EMS-5-3-2\\repositories\\staging"
}
}
- LSR process (1) : /etc/config.lua - listening on default port 8001 (using the out of the box sample Lua scripts)
scripts.log_level = "INFO"
scripts.LUAThing1 = {
file = "thing.lua",
template = "example",
}
scripts.sample = {
file = "sample.lua"
}
- LSR process (2) : /etc/config2.lua - listening on port 8002 (using the out of the box sample Lua scripts)
- This LSR process is started with command "luaScriptResource.exe -cfg .\etc\config2.lua"
scripts.log_level = "INFO"
scripts.script_resource_port = 8002
scripts.LUAThing2 = {file = "thing.lua",
template = "example",
}
scripts.LUAOnlyThing = {
file = "thing.lua",
template = "example",
}
Stage 1 : EMS only
ThingWorx REST API
| Request: Call the GetEdgeThings service on the EMSGateway1 thing | ||||||||||||||||||||||||||||||||||||||||||||||
| POST | twx74neo:8084/Thingworx/Things/EMSGateway1/Services/GetEdgeThings | |||||||||||||||||||||||||||||||||||||||||||||
| Response: As expected, only the remote things flagged as auto_bind are listed | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
| Request: Call the GetRemoteMetadata service on the LUAThing1 thing | |
| POST | twx74neo:8084/Thingworx/Things/LUAThing1/Services/GetRemoteMetadata |
| Response: As expected, remote properties / services and events are not available since the LSR associated with this thing is off. | |
| Unable to Invoke Service GetRemoteMetadata on LUAThing1 : null | |
EMS REST API
| Request: Call the GetEdgeThings service on the LocalEms virtual thing | |
| POST | localhost:8000/Thingworx/Things/LocalEms/Services/GetEdgeThings |
| Response: output is identical to the gateway thing on the platform | |
|
{ "name": "EMSGateway1", "host": "", "port": 8001, "path": "/", "keepalive": 60000, "timeout": 30000, "proto": "http", "user": "", "accept": "application/json" }, { "name": "EMSOnlyThing", "host": "", "port": 8001, "path": "/", "keepalive": 60000, "timeout": 30000, "proto": "http", "user": "", "accept": "application/json" }, { "name": "LUAThing1", "host": "", "port": 8001, "path": "/", "keepalive": 60000, "timeout": 30000, "proto": "http", "user": "", "accept": "application/json" }, { "name": "LUAThing2", "host": "localhost", "port": 8002, "path": "/", "keepalive": 60000, "timeout": 30000, "proto": "http", "user": "", "accept": "application/json"} |
|
LSR REST API
N/A - no LSR process started yet.
Stage 2 : EMS + LSR 1 (8001)

ThingWorx REST API
| Request: Call the GetEdgeThings service on the EMSGateway1 thing | ||||||||||||||||||||||||||||||||||||||||||||||
| POST | twx74neo:8084/Thingworx/Things/EMSGateway1/Services/GetEdgeThings | |||||||||||||||||||||||||||||||||||||||||||||
| Response: LUAThing1 is associated to an LUA script | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
| Request: Call the GetRemoteMetadata service on the LUAThing1 thing | |
| POST | twx74neo:8084/Thingworx/Things/LUAThing1/Services/GetRemoteMetadata |
| Response: Now that the Lua script for LUAThing1 is running, remote properties / services and events are available | |
| {"isSystemObject":false,"propertyDefinitions":{"Script_Pushed_Datetime":{"sourceType":"ThingShape","aspects":{"isReadOnly":false,"dataChangeThreshold":0,"defaultValue":1495619610000,"isPersistent":false,"pushThreshold":0,"dataChangeType":"VALUE","cacheTime":0,"pushType":"ALWAYS"},"name":"Script_Pushed_Datetime","description":"","category":"","tags":[],"baseType":"DATETIME","ordinal":0},"Pushed_InMemory_Boolean":{"sourceType":"ThingShape","aspects":.... | |
EMS REST API
LocalEms::GetEdgeThings returns same output as EMSGateway::GetEdgeThings
LSR REST API (port 8001)
| Request: List all the scripts running in the first LSR | |||||||||||||||||
| GET | localhost:8001/scripts?format=text/html | ||||||||||||||||
| Response: We find our sample script and the script associated with LUAThing1 (the Thingworx script is part of the infrastructure and always there) | |||||||||||||||||
|
|||||||||||||||||
Stage 3 : EMS + LSR 1 (8001) + LSR 2 (8002)

ThingWorx REST API
| Request: Call the GetEdgeThings service on the EMSGateway1 thing | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| POST | twx74neo:8084/Thingworx/Things/EMSGateway1/Services/GetEdgeThings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Response: LUAOnlyThing is now listed and LUAThing2 is associated with a LUA script | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
EMS REST API
LocalEms::GetEdgeThings returns same output as EMSGateway::GetEdgeThings
LSR REST API (port 8002)
| Request: List all the scripts running in the second LSR | |||||||||||||||||
| GET | localhost:8002/scripts?format=text/html | ||||||||||||||||
| Response: Returns the status of all the scripts currently loaded | |||||||||||||||||
|
|||||||||||||||||


