Variable and Setting declaration
Let’s declare the following as global:
le_avdata_AssetInstanceRef_t _assetInstRef[2]; //reference to the 2 asset instances char* _roomName[2]; //array of 2 Variable Name float _currentTemperature[2]; //array of 2 Variable Temperature bool _isAcOn[2]; //array of 2 Variable IsAC_on int _targetTemperature[2]; //array of 2 Setting TargetTemperature int _outsideTemperature = 30; //assuming hot summer le_timer_Ref_t _tempUpdateTimerRef = NULL; //reference to temperature update timer le_timer_Ref_t _avcTimerRef; //reference to the AVC session timer le_avc_StatusEventHandlerRef_t _avcEventHandlerRef = NULL; //reference to AirVantage Controller (AVC) Session handler
Application initialization
- COMPONENT_INIT is called ONCE by Legato framework when the application starts. This function is the placeholder for initialization code.
- This function must return to the framework. Application logic tasks shall be implemented outside of this function using event-handlers; event-driven model application.
Let’s do the following initializations in COMPONENT_INIT:
- Register an AirVantage Controler (AVC) handler function, by calling le_avc_AddStatusEventHandler function, refer to Legato le_avc interface . This registration is required prior starting an AVC sesssion
Call le_avc interface (le_avc_StartSession) to start an AVC Session with AirVantage
_avcEventHandlerRef = le_avc_AddStatusEventHandler(AVsessionHandler, NULL); //register a AVC handler le_result_t result = le_avc_StartSession(); //Start AVC session. Note: AVC handler must be registered prior starting a session if (LE_FAULT == result) { le_avc_StopSession(); le_avc_StartSession(); }
Create a timer to close the AVC session and exit application, in 10 min
_avcTimerRef = le_timer_Create("assetDataAppSessionTimer"); //create timer le_clk_Time_t delay = { 600, 0 }; //allow this app to run for 10 min le_timer_SetInterval(_avcTimerRef, delay); le_timer_SetRepeat(_avcTimerRef, 1); //set repeat to once //set callback function to handle timer expiration event le_timer_SetHandler(_avcTimerRef, timerExpiredHandler); //start timer le_timer_Start(_avcTimerRef);
Create 2 instances of Room Asset, by calling le_avdata_Create, refer to Legato le_avdata interface
_assetInstRef[0] = le_avdata_Create("Room"); //create instance #1 for asset "Room" _assetInstRef[1] = le_avdata_Create("Room"); //create instance #2 for asset "Room"
Assign default values to our 2 instances of Room asset (declared as global variables)
int i = 0; //Assign default value to asset data fields _roomName[i] = (char *) malloc(16); strcpy(_roomName[i], "bedroom"); _currentTemperature[i] = 31.0; _isAcOn[i] = false; _targetTemperature[i] = 19; i++; _roomName[i] = (char *) malloc(16); strcpy(_roomName[i], "living-room"); _currentTemperature[i] = 30.0; _isAcOn[i] = false; _targetTemperature[i] = 19;
Map the data value to instances
for (i=0; i< 2; i++) { le_avdata_SetString(_assetInstRef[i], "Name", _roomName[i]); le_avdata_SetInt(_assetInstRef[i], "Temperature", _currentTemperature[i]); le_avdata_SetBool(_assetInstRef[i], "IsAC_on", _isAcOn[i]); le_avdata_SetInt(_assetInstRef[i], "TargetTemperature", _targetTemperature[i]); }
Register handler, in order to apply Settings and Commands sent by AirVantage. For each data field (settings and commands), call Legato API (le_avdata_AddFieldEventHandler) to register handler functions that will be called by the framework whenever the field is altered by AirVantage.
for (i=0; i< 2; i++) { // call OnWriteSetting() handler whenever the setting "TargetTemperature" is accessed le_avdata_AddFieldEventHandler(_assetInstRef[i], "TargetTemperature", OnWriteSetting, NULL); // call OnCommand() handler whenever the setting "TurnOffAC" is accessed le_avdata_AddFieldEventHandler(_assetInstRef[i], "TurnOffAC", OnCommand, NULL); }
Simulate the rooms temperature, let’s set a timer to update the temperature every 5 seconds
_tempUpdateTimerRef = le_timer_Create("tempUpdateTimer"); //create timer le_clk_Time_t interval = { 5, 0 }; //update temperature every 5 seconds le_timer_SetInterval(_tempUpdateTimerRef, interval); le_timer_SetRepeat(_tempUpdateTimerRef, 0); //set repeat to always le_timer_SetHandler(_tempUpdateTimerRef, updateTemperature); //call updateTemperature function every 5 seconds le_timer_Start(_tempUpdateTimerRef);
Setting Handler functions
- Our application needs to implement handler function to retrieve the value of a Setting (TargetTemperature) set by AirVantage.
- This function should have the prototype defined by le_avdata_FieldHandlerFunc_t, refer to le_avdata interface
- This function shall be registered in COMPONENT_INIT with le_avdata_AddFieldEventHandler
Let’s name it OnWriteVariable:
- void OnWriteVariable(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr)
- This function will be called by the framework whenever AirVantage wants to change the fieldname Setting of our asset instance, referenced by instRef
To retrieve the Setting value pushed by AirVantage, call le_avdata_GetString, le_avdata_GetInt or le_avdata_GetBool
void OnWriteSetting(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr) { int i; for (i=0; i<2; i++) { if (instRef == _assetInstRef[i]) { if (strcmp(fieldName, "TargetTemperature") == 0) { int nTemp; le_avdata_GetInt(instRef, fieldName, &nTemp); //Get the new setting from AirVantage if (nTemp != _targetTemperature[i]) { _isAcOn[i] = true; //let's set the AC status to ON le_avdata_SetBool(instRef, "IsAC_on", _isAcOn[i]); //reflect the new value to instance _targetTemperature[i] = nTemp; le_avdata_SetInt(instRef, fieldName, _targetTemperature[i]); //reflect the new value to instance } } break; } } }
Command Handler functions
- Our application needs to implement handler function to Execute the Command (TurnOffAC) set by AirVantage.
- This function should have the prototype defined by le_avdata_FieldHandlerFunc_t, refer to le_avdata interface
- This function shall be registered in COMPONENT_INIT with le_avdata_AddFieldEventHandler
Let’s name it OnCommand:
- void OnCommand(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr)
This function will be called by the framework whenever AirVantage wants to execute the TurnOffAC Command on our asset instance, referenced by instRef
void OnCommand(le_avdata_AssetInstanceRef_t instRef, const char *fieldName, void *contextPtr) { int i; for (i=0; i<2; i++) { if (instRef == _assetInstRef[i]) { if (strcmp(fieldName, "TurnOffAC") == 0) { _isAcOn[i] = false; //Execute the commande, just turn AC status to OFF le_avdata_SetBool(instRef, "IsAC_on", _isAcOn[i]); //reflect the new value to instance } break; } } }
Simulate temperature
- The handler updateTemperature is called by the framwork every 5 seconds, as set in COMPONENT_INIT
- This function modifies the temperature as follow:
- if AC switch is OFF, then converge the room temperature to the outside temperature
- if AC switch is ON, then converge the room temperature to the targetTemperature (set in AirVantage)
- Simulated room temperatures are then pushed to AirVantage by calling Legato API le_avdata_SetFloat. This is performed automatically by the underlying LWM2M Observe feature when AVC session is opened.
AVC Handler function
- AVC handler function, AVsessionHandler, has been registered in the COMPONENT_INIT function, this is required to start an AVC session with AirVantage
- For this tutorial, let’s do nothing in this function
Exit Application
- The handler timerExpiredHandler is called by the framwork 10min later, as set in COMPONENT_INIT
- This function Close LWM2M session and Quit the application