Difference between revisions of "IoT Restful API"
(→CRUD promises) |
(→Query definition) |
||
(64 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
== Restful API == | == Restful API == | ||
− | *Access control (See [[Access control|Access control]] and [[Access control#Actors|Actors]]) | + | * Jsonld-based Restful API that exposes the Domain Access Protocol resources and allow all CRUD operations on them based on the access control policies (See [[Access control|Access control]] and [[Access control#Actors|Actors]]) |
− | * | + | * To CREATE and UPDATE a resource, it must be supplied in json format according to the semantic definition of its type |
− | * | + | * To GET or DELETE a resource, the crud operation must be executed on the endpoint represented by the resource unique identifier (uri) |
− | *If an error | + | * Embedded collections are represented as JSONArray inside their parent resource. If any of these embedded collection are requested to the API directly, the response will be its json representation (a json of type Collection with a property 'members' containing the collection members) |
+ | * If an error occurs during the execution of a request, the response from the API will be a jsonld of "@type":"/amtech/linkeddata/types/composite/outputMsg" | ||
<syntaxhighlight lang="jsonld"> | <syntaxhighlight lang="jsonld"> | ||
Line 16: | Line 17: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | *If the request is successful a jsonld representation of the resource | + | |
+ | *If the request is successful, the result is a jsonld representation of the resource, with details depending on the requested CRUD operation | ||
+ | |||
+ | === CRUD operations on resources === | ||
+ | API resources support all CRUD operations. Valid credentials must be supplied, meaning that the user must exist and have access (roles/actors) to perform the given CRUD operation on the resource. | ||
+ | Sample CRUD operations on a thing instance : | ||
+ | * Create : via POST on the root endpoint /amtech, passing the json to of the resource to be created | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | curl -X POST -H "Authorization: Basic xxxxx" -H "Content-Type: application/json" -d '{ | ||
+ | "@type": "/amtech/linkeddata/types/composite/entity/Truck", | ||
+ | "@id": "/amtech/things/entities/Truck/truck1", | ||
+ | "description" : "New truck", | ||
+ | "weight":100.0 | ||
+ | }' "https://dap.amtech.mx/amtech" | ||
+ | </syntaxhighlight> | ||
+ | * Read : via GET on the resource uri | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | curl -X GET -H "Authorization: Basic xxxxx" -H "https://dap.amtech.mx/amtech/things/entities/Truck/truck1" | ||
+ | </syntaxhighlight> | ||
+ | * Update : via PUT on the root endpoint /amtech, passing the json to update in the body of the request. The json must include the @id and @type properties, along with all the properties that want to be updated | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | curl -X PUT -H "Authorization: Basic xxxxx" -H "Content-Type: application/json" -d '{ | ||
+ | "@type": "/amtech/linkeddata/types/composite/entity/Truck", | ||
+ | "@id": "/amtech/things/entities/Truck/truck1", | ||
+ | "description" : "Updated description" | ||
+ | }' "https://dap.amtech.mx/amtech" | ||
+ | </syntaxhighlight> | ||
+ | * Delete : via DELETE on the resource uri | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | curl -X DELETE -H "Content-Type: application/json" -u "userId:password" https://dap.amtech.mx/amtech/things/entities/Truck/truck1 | ||
+ | </syntaxhighlight> | ||
===Observation instances=== | ===Observation instances=== | ||
Line 49: | Line 80: | ||
===Thing instances=== | ===Thing instances=== | ||
+ | |||
*CRUD operations | *CRUD operations | ||
− | **/ | + | **/crud |
*CRUD operation promises: | *CRUD operation promises: | ||
**/promise/amtech/things/entities | **/promise/amtech/things/entities | ||
*(See [[Activities#Thing types|Thing types]]) | *(See [[Activities#Thing types|Thing types]]) | ||
+ | |||
+ | === Image fields in thing and observation=== | ||
+ | Fields of type image can be added to things and observations types. Once an image is associated to this field in a thing or observation type, the image is saved in the image storage, and a reference to the image is saved in the thing or observation, in the form of /amtech/static/amtech/things/entities/Truck/truck1/Photo. | ||
+ | |||
+ | The image can then be modified via PUT to that reference endpoint, passing the image base64 representation | ||
===Commands === | ===Commands === | ||
Asynchronous consumption of commands using websocket’s pushing mechanisms (WIP) | Asynchronous consumption of commands using websocket’s pushing mechanisms (WIP) | ||
− | Same as asynchronous consumption of observations. The command received, which is also an observation instance, will have the target type and target | + | Same as asynchronous consumption of observations. The command received, which is also an observation instance, will have the target type and target URI into the targetthings property. (See [[Sensor's network|targetthings]]) |
*(See [[Actions#Send command|Send command]]) | *(See [[Actions#Send command|Send command]]) | ||
===Get observation production configuration === | ===Get observation production configuration === | ||
− | *Get observation | + | *Get observation production configuration from property observationproduction of a thing instance, following all the access control rules (See [[Access control#Actors|Actors]]) |
− | **'/amtech/ | + | **'/amtech/things/entities/<typeId>/<instanceId>/observationproduction' |
− | + | ||
===Get instances by thing type=== | ===Get instances by thing type=== | ||
− | *Get things instances by type for a tenant/user | + | *Get things instances by type for a tenant/user taking into account registered services and access control (See [[Access control#Actors|Actors]]) |
**'/amtech/things/entities/<thingType>' | **'/amtech/things/entities/<thingType>' | ||
Line 83: | Line 119: | ||
}); | }); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | ===Get resources with links (self contained)=== | ||
+ | The API supports URI parameters to retrieving resources resolving its link. There are 2 parameters : selfContained, and fullSelfContained | ||
+ | *selfContained parameter will resolve all embedded links (links whose URIs are direct children of the resource), including for example embedded collections and its members. | ||
+ | *fullSelfContained will resolve all links, embedded and external | ||
+ | In both cases, once a link is resolved, it will not be resolved again, so if it appears a second time in the resource, the link URI will be left unresolved | ||
+ | |||
+ | ===Get image representation of spatial query results === | ||
+ | In order to export the query results as an image, use | ||
+ | https://dap.amtech.mx/offlinemaps | ||
+ | Arguments: | ||
+ | * '''url''': amtech url of the observer, query or thing collection. | ||
+ | * '''ext''': extension of the produced file. Supported extensions are ''.png'' (default) and ''.pdf'' | ||
+ | * '''observation''': json of the observation required to run activity observers | ||
+ | * any query or observer argument | ||
+ | |||
+ | Examples: | ||
+ | * To create a ''.png'' image showing the endCustomers in the map use | ||
+ | https://dap.amtech.mx/offlinemaps?url=/amtech/things/entities/endCustomer | ||
+ | * Use the observer url to show its results. E.g: | ||
+ | https://dap.amtech.mx/offlinemaps?url=/amtech/observers/observerName | ||
+ | * For observers defined inside activity, the observation json must be included | ||
+ | https://dap.amtech.mx/offlinemaps?url=/amtech/activities/myActivity/observers/myObserver&observation={...} | ||
+ | |||
+ | |||
+ | {{Note|Basic authentication is used. Do not forget to use '''user'''/'''tenant''' as username where '''tenant''' is case sensitive}} | ||
+ | |||
+ | ===Get things snapshots - timelilne info=== | ||
+ | To view the snapshots saved for a thing, perform a GET to the system query entitiesTimelineTempQuery, passing the parameter @id with the uri of the thing to get its snapshots <br /> | ||
+ | <syntaxhighlight> | ||
+ | GET https://dap.amtech.mx/amtech/system/queries/entitiesTimelineTempQuery | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Parameters <br/> | ||
+ | * @id with the list of uri of the things to get snapshots Ex. entitiesTimelineTempQuery?@id=["/amtech/things/entities/gpsDevice/gpsDevice1"] | ||
+ | * observationscount : number of snapshots to retrieve (optional) | ||
+ | |||
+ | === Observers API === | ||
+ | Observers defined in the plaform can be executed via REST request to the execution endpoint, passing the uri os the observer to execute. | ||
+ | |||
+ | https://<dapurl>/amtech/observersexec/<observeruri>[?params] | ||
+ | |||
+ | The request also supports parameters to dynamically replace the values of a constraint. The parameter id must be the uri of the constraint to replace. To get the uri of a constraint, GET the list of constraints under the follower uris: | ||
+ | *<observerUri>/entitiesFilter/<thingType>/constraints for the constraints of a thing type included in the observer | ||
+ | *<observerUri>/observationFilter/constraints for the constraints of the observation type included in the observer | ||
+ | |||
+ | ==== Passing constraints as paramters ==== | ||
+ | The request for executing an observer support paramters. | ||
+ | Available params: | ||
+ | |||
+ | * <code>observation</code>: JSON string representation of the observation. May be mandatory depending on the requirements of the observer. | ||
+ | * <code>resourceStatusFilter</code>: You can specify this parameter with the value <code>valid</code> to only return things that passed validation. | ||
+ | * <code>limit</code>: Limit for the number of results. | ||
+ | * <code>noOlderThan</code>: Does not return results older than this date expressed as the number of milliseconds since the epoch (January 1st, 1970, 00:00:00 GMT) | ||
+ | * <code>offsetDate</code>: This works in conjunction with <code>offsetId</code>. This is expected to be the <code>creation date</code> of the thing indicated with the param <code>offsetId</code>. | ||
+ | * <code>offsetId</code>: The results will start with the first thing that is older than the record with this ID. This works in conjunction with the <code>offsetDate</code> and you should indicate either both or none of them. | ||
+ | * <code>tenant</code>: Only return those things available to this tenant. | ||
+ | * <code>includeCount</code>: Set to <code>true</code> to indicate that we are interested in the total number of results for the execution of this observer. <code>false</code> otherwise. | ||
+ | * <code>orderby</code>: field to order results by | ||
+ | * <code>orderdir</code> : direction for ordering (asc or desc) | ||
+ | <br /> | ||
+ | |||
+ | Also, properties of a constraint can be passed as a parameter in the form of <constraintUri>/propertyId=<value>. This will replace the value of that property in the constraint, with the value passed in parameter. | ||
+ | Ex. Passing parameter /amtech/observers/sampleObserver/entitiesFilter/endCustomer/constraints/nameeq/value=newName will replace the "value" of the constraint "nameeq" | ||
+ | |||
+ | ====Target things==== | ||
+ | |||
+ | Example: | ||
+ | |||
+ | <syntaxhighlight lang="jsonld> | ||
+ | { | ||
+ | ... | ||
+ | "targetthings": "[{\"thingType\":\"/amtech/linkeddata/types/composite/entity/truck\",\"thingsId\":[\"truck888\"], \"proximityarea\": \"/amtech/things/entities/customer/customer1\"}]" | ||
+ | ... | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | It allows to establish a relationship between an observation and things instances. It consists of an array of JSON objects having: | ||
+ | * '''thingType''' The URI or just the name of a thing type. This is mandatory. | ||
+ | * '''thingsId''' A set of thing instances which can also be written as full URIs or just simple names. Full URIs can be determined by using the type. | ||
+ | * '''proximityarea''' The URI of a thing instance indicated as the proximity area to these thing instances. | ||
+ | |||
+ | ;Effects from client to server | ||
+ | * It can be configured in an observer to just return instances listed in this property. | ||
+ | * The proximityarea is used at the observation enrichment process to assign target thing instances with a location. | ||
+ | |||
+ | ;Effects from server to client | ||
+ | * It allows to send observations to specific instances. For instance, m2mBridge leverages this functionality to implement centralized management and send observations. | ||
+ | |||
+ | === Query execution API === | ||
+ | Queries can be executed by posting a JSON with the query definition to the endpoint /amtech/queries | ||
+ | |||
+ | ==== Query definition ==== | ||
+ | |||
+ | Required fields | ||
+ | * @type : /amtech/linkeddata/types/composite/query | ||
+ | * resourcetypelist | ||
+ | * resourceurilist | ||
+ | |||
+ | Optional fields | ||
+ | * constraints | ||
+ | * fields | ||
+ | * groupby | ||
+ | * orderby | ||
+ | |||
+ | ==== Sample queries ==== | ||
+ | Get all things of type stpg | ||
+ | { | ||
+ | "@type":"/amtech/linkeddata/types/composite/query", | ||
+ | "resourcetypelist":["/amtech/linkeddata/types/composite/entity/stpg"] | ||
+ | } | ||
+ | |||
+ | Get all things with the given uri | ||
+ | { | ||
+ | "@type":"/amtech/linkeddata/types/composite/query", | ||
+ | "resourceurilist":["/amtech/things/entities/stg/stg555", "/amtech/things/entities/stpg/stpg111"] | ||
+ | } | ||
+ | |||
+ | === Tag data translation service === | ||
+ | This service allows to translate epc tag data between hex notation and epc urn. Ex: | ||
+ | <nowiki>https://dap.amtech.mx/amtech/tdt/hex/tagEncoding/3358788D019D694000008235</nowiki> | ||
+ | will return | ||
+ | <nowiki>{ | ||
+ | resource: "/amtech/tdt/hex/tagEncoding/3358788D019D694000008235", | ||
+ | success: true, | ||
+ | @type: "/amtech/linkeddata/types/composite/outputMsg", | ||
+ | message: "Success", | ||
+ | results: "urn:epc:tag:GRAI-96:2.123444.423333.33333", | ||
+ | targetResourceType: "" | ||
+ | }</nowiki> | ||
+ | a DAP message with the resulting urn. In case of unsuccessful response, the success field will be false and the error message will be included | ||
+ | |||
+ | This endpoint allows also to convert to a beacon ids. In both cases it will return a comma-separated string with a proposal of identification information. This proposal generation can be inverted in order to retrieve back the tag urn from the identification string. For each beacon format the identification string contains the following fields | ||
+ | *iBeacon | ||
+ | **uuid | ||
+ | **mayor | ||
+ | **minor | ||
+ | *eddystone | ||
+ | **namespace | ||
+ | ** instance | ||
+ | |||
+ | The syntax for the endpoint is | ||
+ | <nowiki>https://dap.amtech.mx/amtech/tdt/</nowiki>'''''fromFormat'''''/'''''toFormat'''''/'''''input''''' | ||
+ | where | ||
+ | the allowed formats are | ||
+ | * '''''hex''''': hexadecimal notation of the binary tag | ||
+ | * '''''binary''''': binary tag data | ||
+ | * '''''tagEncoding''''': epc tag urn | ||
+ | * '''''ibeacon''''': ibeacon identification information e.g: ''uuid=2A3358788D0180000000000000000000,mayor=75A5,minor=8235'' | ||
+ | * '''''eddystone''''': eddystone identification information e.g:''namespace=223358788D0000000000,instance=0675A5008235'' | ||
+ | |||
+ | The '''''input''''' field must be the string on the format given as '''''fromFormat''''' | ||
+ | Some examples: | ||
+ | # Conversion from tagEncoding to ibeacon | ||
+ | |||
+ | <nowiki>https://dap.amtech.mx/amtech/tdt/tagEncoding/ibeacon/urn:epc:tag:GRAI-96:2.123444.423333.33333</nowiki> | ||
+ | { | ||
+ | resource: <nowiki>"/amtech/tdt/tagEncoding/ibeacon/urn:epc:tag:GRAI-96:2.123444.423333.33333",</nowiki> | ||
+ | success: true, | ||
+ | @type: "/amtech/linkeddata/types/composite/outputMsg", | ||
+ | message: "Success", | ||
+ | results: "uuid=2A3358788D0180000000000000000000,mayor=75A5,minor=8235", | ||
+ | targetResourceType: "" | ||
+ | } | ||
+ | # Conversion from eddystone to tagEncoding | ||
+ | <nowiki>https://dap.amtech.mx/amtech/tdt/eddystone/tagEncoding/namespace=223358788D0000000000,instance=0675A5008235</nowiki> | ||
+ | { | ||
+ | resource: <nowiki>"/amtech/tdt/eddystone/tagEncoding/namespace=223358788D0000000000,instance=0675A5008235",</nowiki> | ||
+ | success: true, | ||
+ | @type: "/amtech/linkeddata/types/composite/outputMsg", | ||
+ | message: "Success", | ||
+ | results: <nowiki>"urn:epc:tag:GRAI-96:2.123444.423333.33333",</nowiki> | ||
+ | targetResourceType: "" | ||
+ | } | ||
+ | === Barcode encoding/decoding service === | ||
+ | It is posible to decode or encode different types of barcodes. The root path of this service is | ||
+ | <nowiki>https://dap.amtech.mx/amtech/barcode</nowiki> | ||
+ | |||
+ | The available syntaxes are | ||
+ | <nowiki>https://dap.amtech.mx/amtech/barcode/<action>/<barcode format>/<input></nowiki> | ||
+ | <nowiki>https://dap.amtech.mx/amtech/barcode/decode/<input></nowiki> | ||
+ | |||
+ | Where | ||
+ | *'''action''': ''encode'' or ''decode''. | ||
+ | *'''input''': text to encode or ''Base64'' string of image with the barcode to decode. | ||
+ | *'''barcode format''': type of barcode to decode/encode. If not specified (second url option above) then the service try to discover the format. | ||
+ | |||
+ | The handled barcode formats to use are | ||
+ | *1D barcodes | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/upc-code/ UPC_A, UPC_E] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/ean-code/ EAN_8, EAN_13] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/code-39/ CODE_39] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/code-93/ CODE_93] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/code-128/ CODE_128] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/itf-2-of-5/ ITF] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/codabar/ CODABAR] | ||
+ | |||
+ | *2D barcodes | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/qr-code/ QR] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/pdf417/ PDF_417] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/data-matrix/ DATA_MATRIX] | ||
+ | **[https://www.scandit.com/products/barcode-scanner/symbologies/aztec/ AZTEC] | ||
==Asynchronous== | ==Asynchronous== | ||
Line 89: | Line 327: | ||
*([https://en.wikipedia.org/wiki/WebSocket web sockets]) | *([https://en.wikipedia.org/wiki/WebSocket web sockets]) | ||
===Observations=== | ===Observations=== | ||
− | * | + | * Observations can be consumed via websockets, using websocket’s pushing mechanisms (WIP) |
+ | * Supported parameters : | ||
+ | ** client : specifies an indentifier for consuming. Once consumed with an identifier, the observation is no longer available in the system for that identifier. | ||
+ | ** topic : url of the topic to get observations from | ||
+ | ** obstype : observation type to use as filter, for consuming only the observations of that type found in the topic | ||
+ | * A request should be in the form of : | ||
**wss://dap.amtech.mx/amtech/push/things/events?client=<client id>&topic=<topic uri>[&obstype=<obs type>] | **wss://dap.amtech.mx/amtech/push/things/events?client=<client id>&topic=<topic uri>[&obstype=<obs type>] | ||
− | |||
===Commands=== | ===Commands=== | ||
Line 103: | Line 345: | ||
===Things=== | ===Things=== | ||
− | *Consumption through | + | *Consumption through websockets of promise execution results: |
**/promise/amtech/results?client=<client_id>&thingtype=<thingtype>[&thinguri=<thinguri>] | **/promise/amtech/results?client=<client_id>&thingtype=<thingtype>[&thinguri=<thinguri>] | ||
Line 138: | Line 380: | ||
==Clone== | ==Clone== | ||
− | + | There are two endpoints for cloning resources : | |
* /amtech/clone/resourceandlinks<resourceToCloneUri>?newname=<nameForClone> | * /amtech/clone/resourceandlinks<resourceToCloneUri>?newname=<nameForClone> | ||
− | GET on this endpoint | + | A GET on this endpoint will clone the specified resource without persisting it, generating clones for all the links referenced in the resource. Ex. If called with a resource LLRPReader1, that has 2 anntenas, it will generate a clone for the each of the antennas and the LLRPReader. |
* /amtech/clone/resourceflat<resourceToCloneUri>?newname=<nameForClone> | * /amtech/clone/resourceflat<resourceToCloneUri>?newname=<nameForClone> | ||
− | GET on this endpoint | + | A GET on this endpoint will clone the specified resource without persisting it and without cloning the links referenced in the resource. |
− | POST on | + | A POST on either endpoint will clone the resource and persist it |
− | + | There are entities' properties such as "proximity area" and "activity for observation production" whose values are always copied to the new resource as a reference, instead of cloning them. | |
Cloning is supported for : | Cloning is supported for : | ||
− | Entity type | + | * Entity type |
− | Observation type | + | * Observation type |
− | Supported properties | + | * Supported properties |
− | Entity instances | + | * Entity instances |
− | Observation instances | + | * Observation instances |
==CRUD promises== | ==CRUD promises== | ||
− | CRUD promises are like any other CRUD operation on things except that they are asynchronously executed. When you | + | CRUD promises are like any other CRUD operation on things except that they are asynchronously executed. When you execute a PUT, POST or DELETE on the promises endpoint, the corresponding thing will be asynchronously created, updated or deleted by an engine that executes operations sequentially over the same thing instance. |
+ | |||
+ | See [[CRUD promises]] |
Latest revision as of 10:58, 24 February 2021
Contents
- 1 Restful API
- 1.1 CRUD operations on resources
- 1.2 Observation instances
- 1.3 Thing instances
- 1.4 Image fields in thing and observation
- 1.5 Commands
- 1.6 Get observation production configuration
- 1.7 Get instances by thing type
- 1.8 Get resources with links (self contained)
- 1.9 Get image representation of spatial query results
- 1.10 Get things snapshots - timelilne info
- 1.11 Observers API
- 1.12 Query execution API
- 1.13 Tag data translation service
- 1.14 Barcode encoding/decoding service
- 2 Asynchronous
- 3 Clone
- 4 CRUD promises
Restful API
- Jsonld-based Restful API that exposes the Domain Access Protocol resources and allow all CRUD operations on them based on the access control policies (See Access control and Actors)
- To CREATE and UPDATE a resource, it must be supplied in json format according to the semantic definition of its type
- To GET or DELETE a resource, the crud operation must be executed on the endpoint represented by the resource unique identifier (uri)
- Embedded collections are represented as JSONArray inside their parent resource. If any of these embedded collection are requested to the API directly, the response will be its json representation (a json of type Collection with a property 'members' containing the collection members)
- If an error occurs during the execution of a request, the response from the API will be a jsonld of "@type":"/amtech/linkeddata/types/composite/outputMsg"
{
"message":"Resource /amtech/things/entities/gpsDevice/gpsDeviceParkingDemo already exists",
"targetResourceType":"/amtech/linkeddata/types/composite/entity/gpsDevice",
"errorType":"amtech.utils.model.ResourceAlreadyExistException",
"@type":"/amtech/linkeddata/types/composite/outputMsg",
"resource":"/amtech/things/entities/gpsDevice/gpsDeviceParkingDemo",
"success":false,
"messagedetail":""
}
- If the request is successful, the result is a jsonld representation of the resource, with details depending on the requested CRUD operation
CRUD operations on resources
API resources support all CRUD operations. Valid credentials must be supplied, meaning that the user must exist and have access (roles/actors) to perform the given CRUD operation on the resource. Sample CRUD operations on a thing instance :
- Create : via POST on the root endpoint /amtech, passing the json to of the resource to be created
curl -X POST -H "Authorization: Basic xxxxx" -H "Content-Type: application/json" -d '{
"@type": "/amtech/linkeddata/types/composite/entity/Truck",
"@id": "/amtech/things/entities/Truck/truck1",
"description" : "New truck",
"weight":100.0
}' "https://dap.amtech.mx/amtech"
- Read : via GET on the resource uri
curl -X GET -H "Authorization: Basic xxxxx" -H "https://dap.amtech.mx/amtech/things/entities/Truck/truck1"
- Update : via PUT on the root endpoint /amtech, passing the json to update in the body of the request. The json must include the @id and @type properties, along with all the properties that want to be updated
curl -X PUT -H "Authorization: Basic xxxxx" -H "Content-Type: application/json" -d '{
"@type": "/amtech/linkeddata/types/composite/entity/Truck",
"@id": "/amtech/things/entities/Truck/truck1",
"description" : "Updated description"
}' "https://dap.amtech.mx/amtech"
- Delete : via DELETE on the resource uri
curl -X DELETE -H "Content-Type: application/json" -u "userId:password" https://dap.amtech.mx/amtech/things/entities/Truck/truck1
Observation instances
- Getting observation types with property _blankinstancepublished return a blank jsonld ready to be filled and send
- /amtech/linkeddata/types/composite/observation
- Sending observations
- /amtech/things/events
- (See Observations and observation types)
rest.postJson(self.dapUrl + '/amtech/things/events', observation, options).on(
'complete', function(data, response) {
if (response && response.statusCode && response.statusCode !== 200) {
complete(self.buildError(response, "Sending observation"), data);
} else if (data instanceof Error) {
complete(data);
} else if (data['success'] === false) {
complete(self.buildDapError(data, 'At DapClient sendObservation'), data);
} else {
complete();
}
});
- Synchronous consumption of observation instances in topics
- /amtech/things/events?client=<client id>&topic=<topic uri>[&obstype=<obs type>]
- topic (See Topics)
- targetthings (See Target things)
- proximityarea (See Location)
- location (See Location)
- producer (See [[Sensor's network#Observations)
Thing instances
- CRUD operations
- /crud
- CRUD operation promises:
- /promise/amtech/things/entities
- (See Thing types)
Image fields in thing and observation
Fields of type image can be added to things and observations types. Once an image is associated to this field in a thing or observation type, the image is saved in the image storage, and a reference to the image is saved in the thing or observation, in the form of /amtech/static/amtech/things/entities/Truck/truck1/Photo.
The image can then be modified via PUT to that reference endpoint, passing the image base64 representation
Commands
Asynchronous consumption of commands using websocket’s pushing mechanisms (WIP) Same as asynchronous consumption of observations. The command received, which is also an observation instance, will have the target type and target URI into the targetthings property. (See targetthings)
- (See Send command)
Get observation production configuration
- Get observation production configuration from property observationproduction of a thing instance, following all the access control rules (See Actors)
- '/amtech/things/entities/<typeId>/<instanceId>/observationproduction'
Get instances by thing type
- Get things instances by type for a tenant/user taking into account registered services and access control (See Actors)
- '/amtech/things/entities/<thingType>'
rest.get(self.dapUrl + '/amtech/things/entities/gpsDevice', options).on(
'complete', function (data, response) {
if (response && response.statusCode && response.statusCode !== 200) {
complete(self.buildError(response, "Getting plugins instances"), data);
} else if (data instanceof Error) {
complete(data);
} else if ('success' in data && !data['success']) {
complete(self.buildDapError(data, 'At DapClient getPluginsInstances'), data);
} else {
complete(null, data.members);
}
});
Get resources with links (self contained)
The API supports URI parameters to retrieving resources resolving its link. There are 2 parameters : selfContained, and fullSelfContained
- selfContained parameter will resolve all embedded links (links whose URIs are direct children of the resource), including for example embedded collections and its members.
- fullSelfContained will resolve all links, embedded and external
In both cases, once a link is resolved, it will not be resolved again, so if it appears a second time in the resource, the link URI will be left unresolved
Get image representation of spatial query results
In order to export the query results as an image, use
https://dap.amtech.mx/offlinemaps
Arguments:
- url: amtech url of the observer, query or thing collection.
- ext: extension of the produced file. Supported extensions are .png (default) and .pdf
- observation: json of the observation required to run activity observers
- any query or observer argument
Examples:
- To create a .png image showing the endCustomers in the map use
https://dap.amtech.mx/offlinemaps?url=/amtech/things/entities/endCustomer
- Use the observer url to show its results. E.g:
https://dap.amtech.mx/offlinemaps?url=/amtech/observers/observerName
- For observers defined inside activity, the observation json must be included
https://dap.amtech.mx/offlinemaps?url=/amtech/activities/myActivity/observers/myObserver&observation={...}
Note: Basic authentication is used. Do not forget to use user/tenant as username where tenant is case sensitive
Get things snapshots - timelilne info
To view the snapshots saved for a thing, perform a GET to the system query entitiesTimelineTempQuery, passing the parameter @id with the uri of the thing to get its snapshots
GET https://dap.amtech.mx/amtech/system/queries/entitiesTimelineTempQuery
Parameters
- @id with the list of uri of the things to get snapshots Ex. entitiesTimelineTempQuery?@id=["/amtech/things/entities/gpsDevice/gpsDevice1"]
- observationscount : number of snapshots to retrieve (optional)
Observers API
Observers defined in the plaform can be executed via REST request to the execution endpoint, passing the uri os the observer to execute.
https://<dapurl>/amtech/observersexec/<observeruri>[?params]
The request also supports parameters to dynamically replace the values of a constraint. The parameter id must be the uri of the constraint to replace. To get the uri of a constraint, GET the list of constraints under the follower uris:
- <observerUri>/entitiesFilter/<thingType>/constraints for the constraints of a thing type included in the observer
- <observerUri>/observationFilter/constraints for the constraints of the observation type included in the observer
Passing constraints as paramters
The request for executing an observer support paramters. Available params:
-
observation
: JSON string representation of the observation. May be mandatory depending on the requirements of the observer. -
resourceStatusFilter
: You can specify this parameter with the valuevalid
to only return things that passed validation. -
limit
: Limit for the number of results. -
noOlderThan
: Does not return results older than this date expressed as the number of milliseconds since the epoch (January 1st, 1970, 00:00:00 GMT) -
offsetDate
: This works in conjunction withoffsetId
. This is expected to be thecreation date
of the thing indicated with the paramoffsetId
. -
offsetId
: The results will start with the first thing that is older than the record with this ID. This works in conjunction with theoffsetDate
and you should indicate either both or none of them. -
tenant
: Only return those things available to this tenant. -
includeCount
: Set totrue
to indicate that we are interested in the total number of results for the execution of this observer.false
otherwise. -
orderby
: field to order results by -
orderdir
: direction for ordering (asc or desc)
Also, properties of a constraint can be passed as a parameter in the form of <constraintUri>/propertyId=<value>. This will replace the value of that property in the constraint, with the value passed in parameter. Ex. Passing parameter /amtech/observers/sampleObserver/entitiesFilter/endCustomer/constraints/nameeq/value=newName will replace the "value" of the constraint "nameeq"
Target things
Example:
{
...
"targetthings": "[{\"thingType\":\"/amtech/linkeddata/types/composite/entity/truck\",\"thingsId\":[\"truck888\"], \"proximityarea\": \"/amtech/things/entities/customer/customer1\"}]"
...
}
It allows to establish a relationship between an observation and things instances. It consists of an array of JSON objects having:
- thingType The URI or just the name of a thing type. This is mandatory.
- thingsId A set of thing instances which can also be written as full URIs or just simple names. Full URIs can be determined by using the type.
- proximityarea The URI of a thing instance indicated as the proximity area to these thing instances.
- Effects from client to server
- It can be configured in an observer to just return instances listed in this property.
- The proximityarea is used at the observation enrichment process to assign target thing instances with a location.
- Effects from server to client
- It allows to send observations to specific instances. For instance, m2mBridge leverages this functionality to implement centralized management and send observations.
Query execution API
Queries can be executed by posting a JSON with the query definition to the endpoint /amtech/queries
Query definition
Required fields
- @type : /amtech/linkeddata/types/composite/query
- resourcetypelist
- resourceurilist
Optional fields
- constraints
- fields
- groupby
- orderby
Sample queries
Get all things of type stpg {
"@type":"/amtech/linkeddata/types/composite/query", "resourcetypelist":["/amtech/linkeddata/types/composite/entity/stpg"]
}
Get all things with the given uri {
"@type":"/amtech/linkeddata/types/composite/query", "resourceurilist":["/amtech/things/entities/stg/stg555", "/amtech/things/entities/stpg/stpg111"]
}
Tag data translation service
This service allows to translate epc tag data between hex notation and epc urn. Ex:
https://dap.amtech.mx/amtech/tdt/hex/tagEncoding/3358788D019D694000008235
will return { resource: "/amtech/tdt/hex/tagEncoding/3358788D019D694000008235", success: true, @type: "/amtech/linkeddata/types/composite/outputMsg", message: "Success", results: "urn:epc:tag:GRAI-96:2.123444.423333.33333", targetResourceType: "" } a DAP message with the resulting urn. In case of unsuccessful response, the success field will be false and the error message will be included
This endpoint allows also to convert to a beacon ids. In both cases it will return a comma-separated string with a proposal of identification information. This proposal generation can be inverted in order to retrieve back the tag urn from the identification string. For each beacon format the identification string contains the following fields
- iBeacon
- uuid
- mayor
- minor
- eddystone
- namespace
- instance
The syntax for the endpoint is https://dap.amtech.mx/amtech/tdt/fromFormat/toFormat/input where the allowed formats are
- hex: hexadecimal notation of the binary tag
- binary: binary tag data
- tagEncoding: epc tag urn
- ibeacon: ibeacon identification information e.g: uuid=2A3358788D0180000000000000000000,mayor=75A5,minor=8235
- eddystone: eddystone identification information e.g:namespace=223358788D0000000000,instance=0675A5008235
The input field must be the string on the format given as fromFormat Some examples:
- Conversion from tagEncoding to ibeacon
https://dap.amtech.mx/amtech/tdt/tagEncoding/ibeacon/urn:epc:tag:GRAI-96:2.123444.423333.33333 { resource: "/amtech/tdt/tagEncoding/ibeacon/urn:epc:tag:GRAI-96:2.123444.423333.33333", success: true, @type: "/amtech/linkeddata/types/composite/outputMsg", message: "Success", results: "uuid=2A3358788D0180000000000000000000,mayor=75A5,minor=8235", targetResourceType: "" }
- Conversion from eddystone to tagEncoding
https://dap.amtech.mx/amtech/tdt/eddystone/tagEncoding/namespace=223358788D0000000000,instance=0675A5008235 { resource: "/amtech/tdt/eddystone/tagEncoding/namespace=223358788D0000000000,instance=0675A5008235", success: true, @type: "/amtech/linkeddata/types/composite/outputMsg", message: "Success", results: "urn:epc:tag:GRAI-96:2.123444.423333.33333", targetResourceType: "" }
Barcode encoding/decoding service
It is posible to decode or encode different types of barcodes. The root path of this service is
https://dap.amtech.mx/amtech/barcode
The available syntaxes are
https://dap.amtech.mx/amtech/barcode/<action>/<barcode format>/<input> https://dap.amtech.mx/amtech/barcode/decode/<input>
Where
- action: encode or decode.
- input: text to encode or Base64 string of image with the barcode to decode.
- barcode format: type of barcode to decode/encode. If not specified (second url option above) then the service try to discover the format.
The handled barcode formats to use are
- 1D barcodes
- 2D barcodes
Asynchronous
- In order to authenticate the request from a web browser using window.WebSocket object you can put the authentication credentials in the URL as:
- wss://<user>:<pass>@<host>/amtech/push/things/events?client...
- (web sockets)
Observations
- Observations can be consumed via websockets, using websocket’s pushing mechanisms (WIP)
- Supported parameters :
- client : specifies an indentifier for consuming. Once consumed with an identifier, the observation is no longer available in the system for that identifier.
- topic : url of the topic to get observations from
- obstype : observation type to use as filter, for consuming only the observations of that type found in the topic
- A request should be in the form of :
- wss://dap.amtech.mx/amtech/push/things/events?client=<client id>&topic=<topic uri>[&obstype=<obs type>]
Commands
- Asynchronous consumption of commands using websocket’s pushing mechanisms (WIP)
- wss://dap.amtech.mx/amtech/push/things/commands?client=<client id>&thingtype=<thing type>&[&obstype=<obs type>]
Notifications
- Asynchronous consumption of notifications using websockets:
- wss://dap.amtech.mx/amtech/push/notifications[?clientid=<client id>]
- (See Notifications)
Things
- Consumption through websockets of promise execution results:
- /promise/amtech/results?client=<client_id>&thingtype=<thingtype>[&thinguri=<thinguri>]
Example
"use strict"; var websocket = require("websocket"); var wsclient = new websocket.client(); wsclient.on("connectFailed", function (error) { console.log("Connect error: " + error.toString()); }); wsclient.on("connect", function (connection) { console.log("WebSocket client connected"); connection.on("error", function (error) { console.log("Connection error: " + error.toString()); }); connection.on("close", function () { console.log("Connection closed"); }); connection.on("message", function (message) { if (message.type === "utf8") { console.log("Received: '" + message.utf8Data + "'"); } }); process.on('SIGINT', function () { console.log("Closing connection..."); connection.close(); setTimeout(function () { console.log("Closed"); }, 5000); }); }); var token = new Buffer("user/tenant:password").toString("Base64"); wsclient.connect("wss://dap.amtech.mx/amtech/push/notifications", null, null, { Authorization: "Basic " + token });
Clone
There are two endpoints for cloning resources :
- /amtech/clone/resourceandlinks<resourceToCloneUri>?newname=<nameForClone>
A GET on this endpoint will clone the specified resource without persisting it, generating clones for all the links referenced in the resource. Ex. If called with a resource LLRPReader1, that has 2 anntenas, it will generate a clone for the each of the antennas and the LLRPReader.
- /amtech/clone/resourceflat<resourceToCloneUri>?newname=<nameForClone>
A GET on this endpoint will clone the specified resource without persisting it and without cloning the links referenced in the resource.
A POST on either endpoint will clone the resource and persist it
There are entities' properties such as "proximity area" and "activity for observation production" whose values are always copied to the new resource as a reference, instead of cloning them.
Cloning is supported for :
- Entity type
- Observation type
- Supported properties
- Entity instances
- Observation instances
CRUD promises
CRUD promises are like any other CRUD operation on things except that they are asynchronously executed. When you execute a PUT, POST or DELETE on the promises endpoint, the corresponding thing will be asynchronously created, updated or deleted by an engine that executes operations sequentially over the same thing instance.
See CRUD promises