Sensor's network
Contents
Observations and observation types
Observations are the kind of objects that are used by sensors, devices, pieces of software (things in general) to notify about state change, sensor's readings, etc. Like thing's instances, or any other object in our architecture, they have a type that defines its attributes. Usually we differentiate between an observation instance and an observation type but the former is usually called just observation.
Observation types, as any other type, is a JSON-LD that defines the attributes of an observation.
To be able to create an observation you need to firstly define its type. When you create a new observation type, you will find there are a number of core attributes that are present in all observations. In addition to those like name
and description
that you can find in any object, you will find:
- (See Observations types)
- topic
- This is a String. It contains the destination path where this observation will be stored. We will explain later in this document the characteristics of a topic. Like paths in a filesystem you can specify a list of tokes separated by the character '/' to express an specific position in topic's tree. For instance, you can have
/amtech
as a topic but you can also express something more specific like/us/nevada/las_vegas/hotel_x/main_parking/parking_lot_1/movement_sensor
as the topic of an observation generated by the movement sensor that is located in the parking lot 1 of the main parking of Hotel X in Las Vegas. A topic specification can have placeholders. Those will be explained later in this document. Example:
{
...
"topic": "/#{tenantId}/#{country_code}/#{city}",
...
}
(See Topics)
- producer
- A String used to specify the producer of this observation.
- location
- If known, this is the location where this observation took place. It's expressed as a JSON String that contains a WKT specification. The structure of this JSON is explained in the Location's page.
- ocurrence_time
- This is the date and time an observation occurred. It's specified by the producer of the observation.
- detection_time
- This is the date and time an observation is detected in the system. The producer can specify it but it will always be overriden by our system.
properties topic, producer, targetthings and proximityarea can be enrich with placeholders
targetthings
JSON String that specified the things that are related in some way with an observation with the objectives of:
- Define a criteria in the Observer.
- Parse it in a reasoner javascript binding
- Associate thing's proximity area value to the proximity area assign to the field proximityarea.
The following example illustrates an observation type gpsGeolocation, that will be use in an observer for:
- create a new thing type truck with id truck888 at the position send in the observation
- update the position of the thing id truck888 at the position send in the observation
{
"topic": "/amtech/#{country_code}/#{city}",
//targetthings a thing type truck with id truck888
"targetthings": "[{\"thingType\":\"/amtech/linkeddata/types/composite/entity/truck\",\"thingsId\":[\"truck888\"]}]",
"location": "{\"sContext\":\"geo\",\"wkt\":\"POINT(-99.16495264 19.41553490)\"}",
"speed": 0,
"@type": "/amtech/linkeddata/types/composite/observation/gpsGeolocation",
"creationDate": "2016-03-25T11:30:53.135Z",
"guesttenants": [],
"description": "Simulates a gpsGeolocation inside a customer area",
"producer": "888",
"detectiontime": "2015-11-02T23:51:29.000Z",
"longitude": -99.16495264,
"@id": "/amtech/things/observations/gpsGeolocationInCustomer",
"occurrencetime": "2015-11-02T23:51:29.000Z",
"latitude": 19.4155349,
"accuracy": 0,
"altitudeAccuracy": 0,
"heading": 0
}
Simulator
- (See Simulator)
The simulator is a page in the Creator's UE that allows the user to send observations as if they were generated by a thing in the IoT. There you can create your own observation's instances. Once created, you can select one or more observations and hit the Send
button in order to run a simulation. Observations are actually sent to the sensor's network and you can see the result by consuming then from the corresponding topic.
Topics
A topic is a UTF-8 string, which is used by the broker to filter messages for each connected client. A topic consists of one or more topic levels. Each topic level is separated by a forward slash (topic level separator).
/sensor_network/observation_errors/graiEPC
In comparison to a message queue a topic is very lightweight. There is no need for a client to create the desired topic before publishing or subscribing to it, because a broker accepts each valid topic without any prior initialization.
- Each topic maintains the observation types (semantic) that have been sent to it. (See Observations and observation types)
- There is a RESTful API to send and get observations type (See Observation instances)
- Observations from topics can be asynchronously consumed through Websockets (See Asynchronous Observation instances)
- By configurations these observatios are maintained for 1 hour
- Each observation is served to a user once per topic, given the fact that the user can access it
How it works
Security
Topics are automatically discovered when observations get into the sensor's network. It means that they are automatically created if they don't exist and the user sending the observation has the right to do it. When an observation is about to be inserted into a topic, two different things may happen:
- The destination topic already exist. This is the simplest case and for the observation to be delivered, the user sending it must meet one of these requirements:
- His active tenant at the moment of sending the observation matches the tenant of the destination topic.
- His active tenant at the moment of sending the observation must be in the collection of guesttenants for the destination topic.
- The destination topic must include the special member
_ALL
in the guesttenants collection.
- In any other case the operation is forbidden.
- The destination topic doesn't exist. In this case the destination topic is created only if the user sending the observation has the right to do it. Because the destination topic may consist of one or more hierarchical levels, where each topic level is separated by a forward slash, we analyze the existence of each level starting by the one in the top (the root of the hierarchy). Then we analyze one by one each descendant until we get to the final destination topic. For instance, if the destination topic is
/sensor_network/observation_errors/graiEPC
then we analyze the topics existence in the following order:-
/sensor_network
-
/sensor_network/observation_errors
-
/sensor_network/observation_errors/graiEPC
-
- For each one of these topics we do:
- If the topic exists we skip it.
- If the topic doesn't exist and it's the root topic we can freely create it.
- If the topic doesn't exist and it's not the root topic then the active tenant of the user sending the observation must match the tenant of the parent topic.
- Each time a topic is created it will be assigned the user and tenant of the user sending the observation.
- Remarks: If the topic cannot be created then the operation of sending the observation is rejected.
Enrichment
You can find more information about this topic in the observation enrichment page.
CRUD observation
When a CRUD operation is executed on a thing instance, and the type of the instance has been configured to send crud observations, an observation instance of type observationresourcecrud is sent to the configured topic (See Topics) To configure a thing type to produce crud observations:
- Include the observation type observationresourcecrud in the thing type observation production configuration.(See Thing types)
- Include the thing type, with the observation observationresourcecrud,in the observation production configuration of an activity.(See Observation production configuration)
The following example illustrates a crudoperation PUT on a resource @id /amtech/things/observations/llrpAntennaInRoom5586417595299841, the proId changed from oldvalue false to newvalue true (See Observations and observation types)
{
"topic": "/thingsInBoardroom/ccAsync/",
"_tenant": "amtechdemocreator",
"targetthings": "[]",
"@type": "/amtech/linkeddata/types/composite/observation/observationresourcecrud",
"propId": "sendSmoothingLost",
"resourceuri": "/amtech/things/entities/LLRPAntenna/llrpAntennaInRoom",
"resourcetype": "/amtech/linkeddata/types/composite/entity/LLRPAntenna",
"newvalue": "true",
"guesttenants": [],
"oldvalue": "false",
"crudoperation": "PUT",
"producer": "",
"detectiontime": "Tue Apr 26 22:35:57 UTC 2016",
"occurrencetime": "Tue Apr 26 22:35:56 UTC 2016",
"@id": "/amtech/things/observations/llrpAntennaInRoom5586417595299841",
"_user": "amtechdemocreator@amtech.mx"
}
- This observation allows reasoners to focus just on monitoring the changes to specific thing properties, independent of what originated the transformation of the Thing.
Sensor network error
Occurs when there is an error in the process of delivering an observation to its destination topic. Usually occurs in the process of observation enrichment
- topic "/sensor_network/"
- An observation type observationoutputmsg get send to the sensor network topic /sensor_network/observation_errors/[observationTypeName] in the following example is an observation type observationresourcecrud sent with a wrong topic value "message": "Failed registering topic for observation"
{
"topic": "/sensor_network/observation_errors/observationresourcecrud",
"_tenant": "m2mcreator",
"@type": "/amtech/linkeddata/types/composite/observation/observationoutputmsg",
"resource": "{\"topic\":\" /helloWorld/asynch\",\"_tenant\":\"m2mcreator\",
\"targetthings\":\"[]\",
\"@type\":\"/amtech/linkeddata/types/composite/observation/observationresourcecrud\",
\"propId\":\"hwgreetingLabel\",\"resourceuri\":\"/amtech/things/entities/HelloWorld/helloWorld\",
\"resourcetype\":\"/amtech/linkeddata/types/composite/entity/HelloWorld\",
\"newvalue\":\"heyWithError\",\"guesttenants\":[],
\"oldvalue\":\"hey\",\"crudoperation\":\"PUT\",
\"producer\":\"helloWorld\",\"detectiontime\":\"2016-04-22T18:33:11.481Z\",
\"@id\":\"/amtech/things/observations/helloWorld5226521372857087\",
\"occurrencetime\":\"2016-04-22T18:33:10.948Z\",\"_user\":\"m2mcreator@amtech.mx\"}",
"_name": "idbf740e7d83064ba492c9ca33d20617a0",
"resourcetype": "/amtech/linkeddata/types/composite/observation/observationresourcecrud",
"message": "Failed registering topic for observation",
"guesttenants": [],
"producer": "enrichment-topology",
"detectiontime": "Fri Apr 22 18:33:11 UTC 2016",
"@id": "/amtech/things/observations/6de7bf42-2ea6-4140-a8f4-a427bc119701",
"success": false,
"messagedetail":
"Error registering topic '/amtech/things/eventsources/ ': Resource /amtech/things/eventsources/ is not valid for its type definition. Property @idcannot contain blank spaces. ",
"_user": "m2mcreator@amtech.mx"
}