Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

1. Table of Contents


2. General

2.1 Devices

Representation of devices are identified by their unique serial numbers. These data objects carry a subset of information, as well as a list of SensorIds for data sinks, which contain measurement data. With the given API key, the user and the linked devices are identified.

2.2 Sensors

Sensors represent a data sink holding the data of a run. Each sensor has a start and end date. Its sensor id is unique and links to measurements, geolocation and occurrence data.

Once the Device is restarted, a new sensor data sink will be created with a new id.

2.3 Wording

Physical device

A physical device is identified by a serial number and has 1 to n channels.
Each channel can be configured independently (e.g. own measurement interval) and has one or more sensors, which can provide 1 to m different sensor values.
For example;

  • one value: temperature (for a Temperature-Sensor)

  • two-tuples of: relative humidity and temperature (for a rH-sensor)

  • three-tuples of: status, #changes, relative on (for a DI-sensor)

 

Virtual representation with alarming

In elproCLOUD we have a one to one mapping of device and channel.
For the values of a sensor we have an one to n mapping to virtual sensors.

A virtual sensor is created for every configuration of a real sensor and is used to attach different type of alarms to the same sensor value.

2.4 Data format

Note that any JSON accepted and returned by the API must follow the JSON standard as defined in the ECMA-404 standard with the following amendments.

  1. JSON property names are case invariant and no guarantee can be made regarding the casing of names, which are returned by the API. This means that no difference is made between uppercase and lowercase letters in property names.

  2. The relative order of JSON names in responses is not be guaranteed. This means that the order of properties in the responses should not be depended on, when parsing and processing responses.


3. REST-API

The client can request information from elproCLOUD via REST-API. The communication runs typically in the following sequence:

The device will send its data and occurences in defined fix inteval to the elproCLOUD.
There are mechanisms, where the device will send its data directly to the elproCLOUD and will not wait for the next communication interval.

The customer app requests the data from elproCLOUD via the REST-API on demand or in a self defined intervall. This interval should be defined based on a risk-assesment.

Please be aware that some query results are limited

Specification:

3.1 Data sets and general request scheme

The client can request different data sets, including

  • Measurements

  • Geodata

  • Occurences

  • Deviation

3.1.1 Security Scheme Type

Initially, ELPRO sets up an API key for a dedicated user of an organization.

Provide your API authorization code in the Request Header as Key and Value: 

EAPI-ELCLV2

123a45b67_SAMPLE_f12345ab6c789d0         

In case of lack or mismatch, an Error message with HTTP Status 401 “Unauthorized” will be returned.

3.1.2 User Scope

Retrieved data is in the scope of the organization of the authenticated API User. It will be returned with HTTP-Statuscode 200 (Success).

3.1.3 Http Error Codes

400 Bad Request

e.g. missing mandatory parameter

401 Unauthorized

Invalid or missing API Key

404 Resource not found

Invalid serial number or id

406 Not Acceptable

Accept Header should be only application/json

410 License exhausted

Number of queries or datatransfer used up

500 Server Error

Unexpected internal exception

503 Service Temporarily Unavailable

Service down due to maintenance or update

3.2 Version of the REST-API

For the REST-API a versioning mechanism is implemented.

The versioning includes a Major and a Minor number.

Major numbers will provide an interface to the elproCLOUD and will be increased, if the functionality of the interface is dramatically changed. Minor numbers will be increased, if information is added to the returned data structure. 

Major REST-API Versions will be still available via the URL.

  • elprocloud_request_url/api/v1/…    (for v1 of the REST-API)

  • elprocloud_request_url/api/v2/…    (for v2 of the REST-API)

 Major.Minor Versioning will be included in the returned JSON response.

{

"version": "<Major.Minor>",

}

4. Message Queue (AMQP)

  • A “Customer-Queue” is provided using AMQ protocol which is reachable under amqp.elpro.cloud.

  • The Queue-Name is the name of the explicitly provisioned RabbitMQ Queue. Queue and Users are managed by ELPRO.

  • Furthermore a unique username and password for every customer is provided. See below in this document for an example implementation.

  •  Every customer can use his AMQP client of choice to read and acknowledge on the list of message types.

  • The connection is TLS only (Port 443)

  • In Production the Time to live (TTL) of queue data is set to three days.

4.1 Message Models

The Queue Messages will have following basic payload as JSON:

Fieldname

Type

Description

type

String

Possible Message types:

  • eapi_measurement_new

  • eapi_geodata_new

  • eapi_occurrence_new

  • eapi_deviation_enter

  • eapi_deviation_leave

data

JSON object

Inner JSON representation of an info message, see info data models later in this document

4.2 Message Type

Each Type represents a dedicated json payload inside the Data JSON object. So a consumer knows which Data Model is used.

  • eapi_measurement_new

  • eapi_geodata_new

  • eapi_occurrence_new

  • eapi_deviation_enter

  • eapi_deviation_leave

4.3 Data Models

The Data payloads are different for each type.

4.3.1 Measurement

Fieldname

Type

Description

sensorId

Int64

Id for the sensor data representing a data sink.

deviceId

String

Identifier of the device

value

Decimal

Numeric value of the measure

 

timeStamp

DateTimeOffset

DateTime of measure as timezone utc

unit

String

Unit Token

Possible Values:

K,°C,°F, %

unitType

String

Type of unit as text:

  • temperature

  • relative_humidity

4.3.1.1 Example Measurements

Data with type: “eapi_measurement_new”

{
    "type": "eapi_measurement_new",
    "data": {
        "timeStamp": "2022-10-11T16:21:27+00:00",
        "value": 24.6,
        "unit": "°C",
        "unitType": “temperature",
        "deviceId": "951FF00000340",
        "sensorId": "5368"  
    }
}

4.3.2 GeoData

Fieldname

Type

Description

sensorId

Int64

Id for the sensor data representing a data sink.

deviceId

String

Identifier of the device

latitude

Double

Latitude with 8 digits precision

longitude

Double

Longitude with 8 digits precision

timestamp

DateTimeOffset

datetime in timezone utc

accuracy

Decimal

Accuracy in meters

4.3.2.1 Example GeoData

Data with type: “eapi_geodata_new” 

{
    "type": "eapi_geodata_new",
    "data": {
        "timeStamp": "2022-10-11T15:21:24+00:00",
        "latitude": 47.19999075,
        "longitude": 9.50875282,
        "accuracy": 2316,
        "deviceId": "951FF00000340",
        "sensorId": "5369"
    }
}

4.3.3 Occurrence

Fieldname

Type

Description

sensorId

Int64

Id for the sensor data representing a data sink.

deviceId

String

Identifier of the device

timeStamp

DateTime

DateTime of occurrence as timezone utc

typeName

String

"LoggerStatusChange”

previousState

String

Possible values:

"Undefined", "Init", "Shelflife", "Pairing", "Start", "LogDelayed", "LogTransit", LogPaused", "LogArrived", "StopStopped", "StopSleep", "Calibration", "EmergencyReadOut", "FatalError", "ProductionCalibration"

newState

String

4.3.3.1 Example Occurence

Data with type “eapi_occurrence_new” 

{
    "type": "eapi_occurrence_new",
    "data": {
        "timeStamp": "2022-10-11T15:21:24+00:00",
        "typeName": "LoggerStatusChange",
        "previousState": "Start",
        "newState": "LogDelayed",
        "deviceId": "951FF00000340",
        "sensorId": "5369"
    }
}

4.3.4 Deviation

Fieldname

Type

Description

sensorId

Int64

Id for the sensor data representing a data sink.

deviceId

String

Identifier of the device

timestamp

DateTimeOffset

DateTime of deviation as timezone utc

historyType

String

Type of Deviation describring begin or end of deviation.

Possible values:

“enter”
“leave”

deviationType

String

Deviation type, possible values:

"battery",
"failure",
"missing",
"radio",
"limit"

reason

String

Deviation explanation code

limitzone

String (opt.)

Limit Zone code for a limit deviation

Possible values:

L1,L2,L3, H1,H2,H3…

4.3.4.1 Example Deviation Enter

Data with type “eapi_deviation_enter” 

{
    "type": "eapi_deviation_enter",
    "data": {
        "deviceId": "951FF00000340",
        "sensorId": 5763,
        "timeStamp": "2022-10-26T17:00:22+00:00",
        "historyType": "enter",
        "deviationType": "limit",
        "reason": "upper_limit_alarm"
    }
}

4.3.4.2 Example Devation Leave

Data with type “eapi_deviation_leave”

{
    "type": "eapi_deviation_leave",
    "data": {
        "deviceId": "951FF00000340",
        "sensorId": 5763,
        "timeStamp": "2022-10-26T18:00:22+00:00",
        "historyType": "leave",
        "deviationType": "limit",
        "reason": "upper_limit_alarm"
    }
}

4.4 Consume AMQP Messages

4.4.1 Example Client Code with RabbitMQ in C#

 Example Code how to connect to a Queue with .NET and RabbitMQ nuget library:

public ObservableCollection<MessageModel> Messages { get; private set; }

public static IConnection connection;
public static IModel channel;
public static EventingBasicConsumer consumer;

public void Read()
{        
    var serverName = "amqp.elpro.cloud"
    var queueName = "398ab9ae90efce88dcf623cc49e302e1";
    bool autoACK = true;

    try
    {
        // Prepare 
        var factory = new ConnectionFactory()
        {
            HostName = serverName,
            UserName = "user",
            Password = "password",
            Port = 443,
            Ssl = new SslOption() 
            { 
              Enabled = true, 
              ServerName = serverName
            }
        };

        connection = factory.CreateConnection();
        channel = connection.CreateModel();
      
        var routingKey = $"*.eapi_*"; //*.eapi_measurement_new e.g.                        
        Console.WriteLine(" [*] Waiting for msgs.");

        // Consumer
        consumer = new EventingBasicConsumer(channel);
        consumer.Received += (model, ea) =>
        {
            var body = ea.Body.ToArray();
            var messageText = Encoding.UTF8.GetString(body);

            var message = new MessageModel(ea.RoutingKey, messageText);

            Dispatcher.Dispatch(() => Messages.Add(message));
        };

        // Subscribe
        channel.BasicConsume(queue: queueName,
                    autoAck: autoACK,
                    consumer: consumer);

    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error at RabbitMQ.Test: {ex.Message}");
    }
}

5. Connection Details and Technical Specification

  • No labels