API  2.2
TSmarT Software Library
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
cumulocity_2g.c

Example showing the capabilities of the Cumulocity middleware using the cellular 2g interface.

/* @file cumulocity_2g.c
* @author TST
* @version 0.1
* @date 09/08/2013
* @brief This is an example of how to send/recive data from Cumulocity middleware
* using the cellular 2g interface.
*
* This example shows the user how to manage the main functions of the Cumulocty API
* for TSmarT platforms: registering a new device, managing events, alarms and operations.
*
* To run this example is necessary to be previously registered in the Cumulocity middleware.
* https://cumulocity.com/
*
* Once you have access to Cumulocity, users shall set their account details in the definitions below:
* - TENANT_ACCOUNT
* - USER_ACCOUNT
* - PASSWORD_ACCOUNT
* - API_KEY_ACCOUNT
*
*
* The interface selection is really done during compiling process. So you shall select
* the adequate interface for the application(CELLULAR_2G for this example) enabling or
* disabling the following definitions located in the App.defs file in the application
* folder:
*
* MIDDELWARE_INTERFACE = ETHERNET
* MIDDELWARE_INTERFACE = WIFI
* MIDDELWARE_INTERFACE = CELLULAR_2G
*
* After selecting one of them, users only have to use the functions of the interface selected
* besides of the common API functions to program their applications.
*
* @note To run this application it's necessary to set some cellular 2g network parameters:
* - PIN code -------> Personal identification number.
* - APN ------------> Access Point Name.
* - Login ----------> Network user name.
* - Password -------> Network password.
*
* @note This application uses the debug UART to display debug information like IP address asigned, device
* identifier, alarm identifier, etc.
* According to use it, users should set the next configuration in their serial communication program:
* - Baud rate -----> 115200
* - Word length ---> 8 bits
* - Parity --------> none
* - Stop bit ------> 1
* - Flow control --> none
*
*/
/* ---------------------------------------- System headers ----------------------------------------------------------------*/
#include "tsmart.h"
/* ---------------------------------------- Debug UART --------------------------------------------------------------------*/
#define APP_RX_BUFFER_SZ 10
static uint8_t app_rx_buf[APP_RX_BUFFER_SZ];
/* ---------------------------------------- Cellular 2G Interface Variables/Definitions -----------------------------------*/
/* This is the specific configuration for cellullar 2g, Set them */
/* Set SIM configuration */
#define PIN_CODE "<SET YOUR PIN CODE>"
#define APN "<SET YOUR APN>"
#define LOGIN "<SET YOUR LOGIN>"
#define PASSWORD "<SET YOUR PASSWORD>"
static tsmart_cumulocity_cellular_2g_config_t cellular_config = {
.pin_code = PIN_CODE,
.ip_ttl = 64,
.ip_frag_timeo = 60,
.tcp_maxinitwin = 0,
.tcp_rexmt_max = 64,
.tcp_rexmt_maxcnt = 12,
};
static tsmart_cumulocity_cellular_2g_network_t cellular_2g_network= {
.apn = APN,
.login = LOGIN,
.password = PASSWORD,
.time_to_connect = 1200,
};
/* ---------------------------------------- Application Variables/Definitions ---------------------------------------------*/
/* Cumulocity credentials */
#define TENANT_ACCOUNT "<SET YOUR TENANT>\0"
#define USER_ACCOUNT "<SET YPUR USER>\0"
#define PASSWORD_ACCOUNT "<SET YOUR PASSWORD>\0"
#define API_KEY_ACCOUNT "<SET YOUR API-KEY>\0"
/* Device parameters */
#define DEVICE_NAME "TSMART001\0"
#define DEVICE_TYPE "Counter\0"
#define HW_MODEL "TSmoTe\0"
#define HW_REVISION "2.2\0"
#define HW_SERIALNUMBER "00051\0"
/* Task synchronization */
static xQueueHandle application_mutex;
static uint8_t debug_uart[400];
/* ---------------------------------------- Encoded buffer account details ------------------------------------------------*/
static uint8_t details_account_base64encoded[100];
/* ---------------------------------------- Sensors -----------------------------------------------------------------------*/
#define N_SENSORS 3
/* Sensor names */
#define TEMPERATURE "temperature"
#define HUMIDITY "humidity"
#define STATUS_1 "status_1"
/* Units */
#define DEGREES "C"
#define PERCENTAGE "%"
#define DIMENSIONLESS ""
/* Alarm */
#define ALARM_TYPE "Alarm_1"
#define ALARM_MESSAGE "TSMART_ALARM1\0"
/* Event */
#define EVENT_TYPE "EVENT_1"
#define EVENT_MESSAGE "Initialization OK\0"
/* Account details */
static tsmart_cumulocity_account_t account = {
/* Account */
.tenant = TENANT_ACCOUNT,
.username = USER_ACCOUNT,
.password = PASSWORD_ACCOUNT,
.api_key = API_KEY_ACCOUNT,
.authorization = details_account_base64encoded,
};
/* Device description */
static tsmart_cumulocity_device_t device = {
.name = DEVICE_NAME,
.type = DEVICE_TYPE,
.model = HW_MODEL,
.serial_number = HW_SERIALNUMBER,
.revision = HW_REVISION,
};
/* ---------------------------------------- Available Sensors -------------------------------------------------------------*/
/* Sensor variables */
static int32_t temperature;
static double humidity;
static uint8_t status_1[10]= "active\0";
/* Sensor structure */
static tsmart_cumulocity_sensor_t sensors[N_SENSORS] = {
{ /* Temperature sensor */
.name = TEMPERATURE,
.unit = DEGREES,
.value.integer_value = {
.value_type_id = TSMART_CUMULOCITY_INTEGER,
.value = &temperature,
}
},{
/* humidity sensor */
.name = HUMIDITY,
.unit = PERCENTAGE,
.value.double_value = {
.value_type_id = TSMART_CUMULOCITY_DOUBLE,
.value = &humidity,
}
},{
/* Status 1 sensor */
.name = STATUS_1,
.unit = DIMENSIONLESS,
.value.str_value = {
.value_type_id = TSMART_CUMULOCITY_STRING,
.value = status_1,
}
}
};
/* ---------------------------------------- Alarms ------------------------------------------------------------------------*/
static tsmart_cumulocity_alarm_t alarm = {
.type = ALARM_TYPE,
.text = ALARM_MESSAGE,
};
/* ---------------------------------------- Events ------------------------------------------------------------------------*/
static tsmart_cumulocity_event_t event = {
.type = EVENT_TYPE,
.text = EVENT_MESSAGE,
};
/* ---------------------------------------- Operation ---------------------------------------------------------------------*/
/* Operations to be created */
static int32_t param1 = 2;
static double param2 = 3.3;
static uint8_t param3[] = "OK";
static uint8_t failure_message[]="It was impossible to set config1\0";
/* Operations params */
static tsmart_cumulocity_param_t op_param[3] = {
{ /* Parameter 1 */
.name = "param1\0",
.value.integer_value = {
.value_type_id = TSMART_CUMULOCITY_INTEGER,
.value = &param1,
}
},{
/* Parameter 1 */
.name = "param2\0",
.value.double_value = {
.value_type_id = TSMART_CUMULOCITY_DOUBLE,
.value = &param2,
}
},{
/* Parameter 1 */
.name = "param3\0",
.value.str_value = {
.value_type_id = TSMART_CUMULOCITY_STRING,
.value = param3,
}
}
};
static tsmart_cumulocity_op_t operation = {
.model = "config_model\0",
.n_param = 3,
.param = op_param,
};
/* Operations to be registed */
/* OP1: variables */
int32_t op1_param1;
/* OP2: variables */
int32_t op2_param1;
double op2_param2;
/* OP3: variables */
int32_t op3_param1;
double op3_param2;
uint8_t op3_param3[10];
static uint8_t param_name1[50];
static uint8_t param_name2[50];
static uint8_t param_name3[50];
/* Op1: parameters */
tsmart_cumulocity_param_t op1_param[1] = {
{
/* Parameter 1 */
.name = param_name1,
.value.integer_value = {
.value_type_id = TSMART_CUMULOCITY_INTEGER,
.value = &op1_param1,
}
}
};
/* Op2: parameters */
tsmart_cumulocity_param_t op2_param[2] = {
{
/* Parameter 1 */
.name = param_name1,
.value.integer_value = {
.value_type_id = TSMART_CUMULOCITY_INTEGER,
.value = &op2_param1,
}
},{
/* Parameter 2 */
.name = param_name2,
.value.double_value = {
.value_type_id = TSMART_CUMULOCITY_DOUBLE,
.value = &op2_param2,
}
}
};
/* Op3: parameters */
tsmart_cumulocity_param_t op3_param[3] = {
{
/* Parameter 1 */
.name = param_name1,
.value.integer_value = {
.value_type_id = TSMART_CUMULOCITY_INTEGER,
.value = &op3_param1,
}
},{
/* Parameter 2 */
.name = param_name2,
.value.double_value = {
.value_type_id = TSMART_CUMULOCITY_DOUBLE,
.value = &op3_param2,
}
},{
/* Parameter 3 */
.name = param_name3,
.value.str_value = {
.value_type_id = TSMART_CUMULOCITY_STRING,
.value = op3_param3,
}
}
};
/* Operations to be registered and available to be gotten */
tsmart_cumulocity_op_t got_operation[3] = {
{
/* operation 1 */
.model = "model1\0",
.n_param = 1,
.param = op1_param,
},{
/* operation 2 */
.model = "model2\0",
.n_param = 2,
.param = op2_param,
},{
/* operation 3 */
.model = "config_model\0",
.n_param = 3,
.param = op3_param,
}
};
/* Operation raw buffer */
static uint8_t op_raw_buffer[100];
/* Local IP address */
/* ---------------------------------------- Application Task --------------------------------------------------------------*/
/* @brief CUMULOCITY task.
*
* This task registers a new device in cumulocity middleware and manages
* the alarms and events. In addition it creates an operation and gets it
* form the cumulcoty. After that, it sends periodically mesures to
* cumulocity middleware.
*
* @param pvParameters
*/
void vCC(void *pvParameters){
/* Variables */
static tsmart_cumulocity_buffer_t cumulocity_buffer;
static uint8_t i=0;
static uint8_t j=0;
static tsmart_rtc_time_t time;
uint8_t dtoa_buf[17];
double a;
int8_t index_op;
uint32_t op_raw_id;
TSMART_UART_Send(&tsmart_uart2, "Cumulocity Cellular 2G example\r\n", strlen("Cumulocity Cellular 2G example\r\n"), 1000/portTICK_RATE_MS);
/* Set Time */
time.year = 2013;
time.month = 8;
time.day = 12;
time.hour = 11;
time.minute = 0;
time.second = 0;
/* Set the time */
/* Start module 2G */
if(TSMART_CUMULOCITY_CELLULAR_2G_Start(&cellular_config) != TSMART_PASS){
if(TSMART_CUMULOCITY_CELLULAR_2G_Start(&cellular_config) != TSMART_PASS){
for(;;);
}
}
/* Attach to network */
if(TSMART_CUMULOCITY_CELLULAR_2G_NetworkAttachment(&cellular_2g_network) != TSMART_PASS){
for(;;);
}
/* Read local IP */
if( TSMART_CUMULOCITY_ReadIP(&local_ipv4) != TSMART_PASS){
for(;;);
}
sprintf(debug_uart, "IP: %d.%d.%d.%d\r\n", local_ipv4.v0, local_ipv4.v1, local_ipv4.v2, local_ipv4.v3);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
/* Task synchronization */
xQueueSend(application_mutex, &i, 0);
/* Encoder credentials */
TSMART_CUMULOCITY_Base64Encoder(&account, &cumulocity_buffer, details_account_base64encoded);
/* Register device */
if(TSMART_CUMULOCITY_RegiserDevice(&account, &device, &cumulocity_buffer) != TSMART_PASS){
for(;;);
}
/* Register mesurements */
if(TSMART_CUMULOCITY_RegisterMesurment(&account, device.id, sensors, 3, &cumulocity_buffer) != TSMART_PASS){
for(;;);
}
/* Register operations */
if(TSMART_CUMULOCITY_RegisterOperation(&account, device.id, got_operation, 3, &cumulocity_buffer) != TSMART_PASS){
for(;;);
}
sprintf(debug_uart, "Device registered - %d\r\n", device.id);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
/* Rise alarm */
alarm.time.year = time.year;
alarm.time.month = time.month;
alarm.time.day = time.day;
alarm.time.hour = time.hour;
alarm.time.minute = time.minute;
alarm.time.second = time.second;
if(TSMART_CUMULOCITY_RiseAlarm(&account, device.id, &alarm, &cumulocity_buffer)!= TSMART_PASS){
for(;;);
}
sprintf(debug_uart, "Alarm Rised - %d\r\n", alarm.id);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
/* Update alarm */
if(TSMART_CUMULOCITY_UpdateAlarm(&account, device.id, &alarm, &cumulocity_buffer)!= TSMART_PASS){
for(;;);
}
TSMART_UART_Send(&tsmart_uart2, "Alarm Updated\r\n", strlen("Alarm Updated\r\n"), 1000/portTICK_RATE_MS);
/* Create Event */
event.time.year = time.year;
event.time.month = time.month;
event.time.day = time.day;
event.time.hour = time.hour;
event.time.minute = time.minute;
event.time.second = time.second;
if(TSMART_CUMULOCITY_CreateEvent(&account, device.id, &event, &cumulocity_buffer)!= TSMART_PASS){
for(;;);
}
sprintf(debug_uart, "Event Create - %d\r\n", event.id);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
/* Create operation */
if(TSMART_CUMULOCITY_CreateOperation(&account, device.id, &operation, &cumulocity_buffer) != TSMART_PASS){
for(;;);
}
TSMART_UART_Send(&tsmart_uart2, "Operation created\r\n", strlen("Operation created\r\n"), 1000/portTICK_RATE_MS);
/* Get last operation */
index_op = TSMART_CUMULOCITY_GetOperation(&account, device.id, TSMART_CUMULOCTITY_PENDING, 3, got_operation, &cumulocity_buffer);
if(index_op < 0){
for(;;);
}
sprintf(debug_uart, "Operation id: %d model:%s\r\n", got_operation[index_op].id, got_operation[index_op].model);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
sprintf(debug_uart, "n params: %d\r\n", got_operation[index_op].n_param);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
for(i = 0; i < got_operation[index_op].n_param; i++){
switch(got_operation[index_op].param[i].value.value_type.value_type_id){
sprintf(debug_uart, "%s - %d\r\n", got_operation[index_op].param[i].name, *got_operation[index_op].param[i].value.integer_value.value);
break;
memcpy(&a, got_operation[index_op].param[i].value.double_value.value, sizeof(a));
sprintf(debug_uart, "%s - %s\r\n", got_operation[index_op].param[i].name, TSMART_DoubleToAscii(a, 9, dtoa_buf));
break;
sprintf(debug_uart, "%s - %s\r\n", got_operation[index_op].param[i].name, got_operation[index_op].param[i].value.str_value.value);
break;
default:
break;
}
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
}
/* Get Raw operation */
if(TSMART_CUMULOCITY_GetRawOperation(&account, device.id, TSMART_CUMULOCTITY_PENDING, &op_raw_id, op_raw_buffer, &cumulocity_buffer) != TSMART_PASS){
for(;;);
}
sprintf(debug_uart, "\r\n\r\noperation raw ---> %d\r\n%s\r\n\r\n", op_raw_id, op_raw_buffer);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
/* Update operation */
if(TSMART_CUMULOCITY_UpdateStatusOperation(&account, operation.id, TSMART_CUMULOCTITY_FAILED, failure_message, &cumulocity_buffer) != TSMART_PASS){
for(;;);
}
TSMART_UART_Send(&tsmart_uart2, "Operation Updated\r\n", strlen("Operation Updated\r\n"), 1000/portTICK_RATE_MS);
/* Monitoring */
for(;;){
/* Set vaules */
temperature = i;
humidity = 1.6 + i;
sprintf(status_1, "active");
/* Set time */
for(j=0; j<= N_SENSORS; j++){
sensors[j].time.year = time.year;
sensors[j].time.month = time.month;
sensors[j].time.day = time.day;
sensors[j].time.hour = time.hour;
sensors[j].time.minute = time.minute;
sensors[j].time.second = time.second;
}
/* Send mesurement */
TSMART_CUMULOCITY_SendMeasurement(&account, device.id, DEVICE_TYPE, sensors, N_SENSORS, &cumulocity_buffer);
/* Reports about the sending */
memcpy(debug_uart, cumulocity_buffer.buffer, 13);
sprintf(&debug_uart[13], "- %d\r\n", i++);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
vTaskDelay(500/portTICK_RATE_MS);
}
/* Unregister device */
if(TSMART_CUMULOCITY_UnregisterDevice(&account, device.id, &cumulocity_buffer) != TSMART_PASS){
for(;;);
}
TSMART_UART_Send(&tsmart_uart2, "Device registered\r\n", strlen("Device registered\r\n"), 1000/portTICK_RATE_MS);
/* End task */
for(;;);
}
/* @brief CC_NOTIF task.
*
* Cumulocity notification task is waiting for the new notification about
* the network 2G or cellular 2g device failures.
*
* @param pvParameters
*/
void vCC_NOTIF(void *pvParameters){
uint8_t v;
/* Task synchronization */
xQueueReceive(application_mutex, &v, portMAX_DELAY);
for(;;){
/* Wait for new notification */
switch(notif){
/* GPRS network failure:de-attach form GPRS network */
for(;;);
}
break;
/* Stop module */
/* Start module */
if(TSMART_CUMULOCITY_CELLULAR_2G_Start(&cellular_config) != TSMART_PASS){
for(;;);
}
break;
default:
break;
}
/* Attach to network */
if(TSMART_CUMULOCITY_CELLULAR_2G_NetworkAttachment(&cellular_2g_network) != TSMART_PASS){
for(;;);
}
/* Read new IP */
if(TSMART_CUMULOCITY_ReadIP(&local_ipv4) != TSMART_PASS){
for(;;);
}
sprintf(debug_uart, "IP: %d.%d.%d.%d\r\n", local_ipv4.v0, local_ipv4.v1, local_ipv4.v2, local_ipv4.v3);
TSMART_UART_Send(&tsmart_uart2, debug_uart, strlen(debug_uart), 1000/portTICK_RATE_MS);
}
}
/*
* @brief init() function
*
* This is the first thing that the user must do for using TSmarT.
* It initializes the specific hardware resources (CELLULAR, GPS, AI, DIO, MODBUS, MSA...)
* and software resources (queues, mutex, tasks...) for the user application.
*
* The way to fill in this function properly is to initialize first
* hardware resources and after that software resources.
*
* This function must return: TSMART_PASS when every thing is OK or
* TSMART_FAIL when a failure happened.
*
* @return
* @arg TSMART_PASS
* @arg TSMART_FAIL
*/
int32_t init() {
/* Variables */
static tsmart_uart_config_t tsmart_uart_config;
/* ************************************************************************* */
/* Debug Mode */
/* ************************************************************************* */
/* ************************************************************************* */
/* Initialize resources */
/* ************************************************************************* */
/* Initialize Real-time clock */
/* Initialize cellular 2G interface for Cumulocity */
if (TSMART_CUMULOCITY_CELLULAR_2G_Init() != TSMART_PASS){
return TSMART_FAIL;
}
/* Initialize Debug UART */
tsmart_uart_config.baud_rate = 115200;
tsmart_uart_config.flow_control = TSMART_UART_FC_NONE;
tsmart_uart_config.parity_bit = TSMART_UART_PARITY_NONE;
tsmart_uart_config.word_length = TSMART_UART_WORDLENGTH_8B;
tsmart_uart_config.stop_bit = TSMART_UART_STOPBITS_1;
tsmart_uart_config.rx_buf_sz = APP_RX_BUFFER_SZ;
tsmart_uart_config.rx_buf = app_rx_buf;
tsmart_uart_config.use_dma = TSMART_UART_DMA_RX_TX;
tsmart_uart_config.use_tim = TSMART_UART_TIM_SW;
TSMART_UART_Init(&tsmart_uart2, &tsmart_uart_config);
/* ************************************************************************* */
/* Application task */
/* ************************************************************************* */
/* Task synchronization */
application_mutex = xQueueCreate(1, sizeof(uint8_t));
if (application_mutex == NULL){
return TSMART_FAIL;
}
/* Create Cumulocity task */
if(xTaskCreate(vCC, "CC", 1024, NULL, 7, NULL) != pdPASS){
return TSMART_FAIL;
}
/* Create notification Cumulocity task */
if(xTaskCreate(vCC_NOTIF, "CC_NOTIF", 512, NULL, 8, NULL) != pdPASS){
return TSMART_FAIL;
}
/* Everything OK */
return TSMART_PASS;
}