Introduction

 

This is a set of API calls that allow users to work within the system, get metering data, and other data from the system. This will be a subscription based service allowing users to setup a subscription for all the data they want. There will be a few different classifications of this data and we will enforce how these are retrieve by placing each LID into one classification or another: 

  • Periodic data – This data is updated on some periodic interval known by the system. This will always be subscribed to. 

  • One time data – This data is typically not updated and would be retrieved once at startup and held by the running agent. 

  • Frequently Requested data – This is data that is not periodic, however might be asked for routinely when processing other data, such as system time. Also, these are typically not ILIDs. 

 

This page presents a detailed description of the APIs exposed by the SDK. 

 

Registration 

 

ApiRegisterAgent 

AgentApiReturnType ApiRegisterAgent (uint32_t agentId, const char* name, const char* description) 

This is the first API call any running agent should make. It is critical to register your agent within the system before proceeding with other calls. 

Errors Returned: 

API_ERROR_NULL_POINTER_GIVEN 

 Null pointers may not be used for name or description. 

API_ERROR_INVALID_AGENT_ID 

 0 is a reserved agentId, and may not be used. 

 

ApiDeregisterAgent 

AgentApiReturnType ApiDeregisterAgent () 

An agent may remove themselves from the system by calling this API. This should not be called regularly; this should only be used if the agent believes they are being uninstalled from the system. This will remove all agent data from inside the system, so it should be used with caution. 

Errors returned: 

API_ERROR_AGENT_NOT_REGISTERED 

 Agent has not registered before trying to deregister. Call ApiRegisterAgent() before deregistering. 

Configuration 

FeatureConfigurationListCreate 

FeatureConfigurationListHandle* FeatureConfigurationListCreate(); 

Called to create a FeatureConfigurationListHandle

 

FeatureConfigurationListFree 

FeatureConfigurationListHandle* AgentLidListFree(void* featureConfigurationListHandleIn); 

Used to destroy a FeatureConfigurationListHandle that is no longer needed. 

Errors returned: 

API_ERROR_NULL_POINTER_GIVEN 

 featureConfigurationListHandleIn must not be null. 

API_ERROR_WRONG_POINTER_TYPE 

 featureConfigurationListHandleIn must be a pointer to a created and valid FeatureConfigurationList. 

FeatureConfigurationListResetIteration 

AgentApiReturnType FeatureConfigurationListResetIteration (FeatureConfigurationListHandle* featureConfigurationListHandle); 

Called to reset the iteration through a FeatureConfigurationList back to the beginning of the list. Good practice would call for this to be called whenever a FeatureConfigurationListHandle is given to another API interface, as the API does not guarantee preservation of internal iterator state. 

 
Errors returned: 

API_ERROR_NULL_POINTER_GIVEN 

 featureConfigurationListHandle must not be null. 

API_ERROR_WRONG_POINTER_TYPE 

 featureConfigurationListHandle must be a pointer to a created and valid FeatureConfigurationList. 

FeatureConfigurationListAddFeatureId 

void FeatureConfigurationListAddLid(FeatureConfigurationListHandle* featureConfigurationListHandle, uint32_t featureId); 

Called to add a FeatureId to FeatureConfigurationListHandle. Used when assembling a request for feature configuration(s). 

Errors returned: 

API_ERROR_NULL_POINTER_GIVEN 

 featureConfigurationListHandle must not be null. 

API_ERROR_WRONG_POINTER_TYPE 

 featureConfigurationListHandle must be a pointer to a created and valid FeatureConfigurationList. 

FeatureConfigurationListGetNext 

void FeatureConfigurationListGetNext(FeatureConfigurationListHandle* featureConfigurationListHandle, uint32_t* featureId, uint32_t* configId, uint32_t* featureVersion, uint32_t* configurationLength, char** configurationBlobStream); 

Called to get the next feature configuration out of the FeatureConfigurationList. Will iterate through the list after retrieval. To start from the beginning before iterating through, use FeatureConfigurationListResetIteration()

Errors returned: 

API_ERROR_NULL_POINTER_GIVEN 

 featureConfigurationListHandle and all parameter pointers must not be null. 

API_ERROR_WRONG_POINTER_TYPE 

 featureConfigurationListHandle must be a pointer to a created and valid FeatureConfigurationList. 

API_END_OF_LIST 

 Returned when the end of the FeatureConfigurationList has been reached. If this is returned, the configuration values are not valid. 

ApiGetAndSubscribeToConfiguration 

AgentApiReturnType ApiGetAndSubscribeToConfiguration (FeatureConfigurationListHandle* featureConfigurationListHandle, FunctionPointer* pointerToCallback); 

Allows an agent to retrieve the current configuration associated with a feature or features. The FeatureConfigurationListHandle should be preallocated by calling FeatureConfigurationListCreate(), and the desired feature(s) added by calling FeatureConfigurationListAddFeatureId() for each desired feature. Then this call can be made. If API_SUCCESS is returned, the list that was passed to the call should now be iterated through via FeatureConfigurationGetNext() as long as that API returns API_SUCCESS.end of the list is reached when that call returns API_END_OF_LIST. 

In addition to a list of feature configurations to retrieve, this call also accepts a FunctionPointer* to a callback that is able to receive feature configuration updates that may occur while the agent is running. These updates should be received and parsed the same way that the result of the initial call to ApiGetAndSubscribeToConfiguration() is. The callback should take the form: 

AgentApiReturnType MyConfigurationCallback (FeatureConfigurationListHandle* featureConfigurationListHandle); 

It is noteworthy that the API will attempt to filter configurations based on feature ids that it believes are relevant to the agent. This is determined based on an aggregation of all feature configurations that have previously been requested from that agent via ApiGetAndSubscribeToConfiguration(). 

 

 

Access to Meter Data 

ApiSubscribeToPeriodicData 

AgentApiReturnType ApiSubscribeToPeriodicData(FunctionPointer* pointerToCallback, SubscriptionType type, uint32_t intervalSeconds, LidListHandle * lidList) 

On start-up, the agent will register a callback method that it wishes to have called when periodic data is available. This data will be returned as a list of ILIDs that the user can iterate through. 

The callback prototype is as follows: 

void MyCallBack (LidListHandle* lidList); 

The lidList passed here is FREED after this callback returns from you; keeping a pointer to it is dangerous. If you need values from it, copy it over to your own list using the LidList helper methods. 

LidListHandle in this document is synonymous with void*. This is a structure to which the API caller has no visibility; the set of functions provided through this API should be used manipulate it. See LidList API calls for this below. 

The callback provided is called based on the subscription type provided. 

Enum SubscriptionType 
  
{ 
  
  ON_DATA_CHANGE_ONLY // Callback occurs when data changes (!> 1/sec) 
  
  ON_PERIOD_ONLY // Callback occurs every //interval// whether data changed or not. 
  
  ON_DATA_CHANGE_AND_PERIOD // Callback occurs on //interval//, but only if data changed 
  
  ON_DATA_CHANGE_OR_PERIOD // on //interval// or if data changes (!> 1/sec) 
  
} 

Errors returned: 

API_ERROR_NULL_POINTER_GIVEN 

 pointerToCallback and/or lidList may not be null. 

API_ERROR_WRONG_POINTER_TYPE 

 lidList must be a pointer to a valid LidList. 

API_ERROR_AGENT_NOT_REGISTERED 

 Agent has not registered before trying to subscribe to data. Call ApiRegisterAgent() before trying subscribe. 

API_ERROR_INVALID_LID_VALUE 

 An attempt was made to subscribe to a lid that does not exist. Read ApiGetLastInvalidLid() to get the lid that caused the error. 

API_ERROR_ONE_TIME_LID_SUBSCRIBE_ATTEMPT 

 An attempt was made to subscribe to a lid that should only be read once, at startup. Read ApiGetLastInvalidLid() to get the lid that caused the error. 

ApiUnsubscribeFromPeriodicData 

AgentApiReturnType ApiUnsubscribeFromPeriodicData() 

If an agent no longer wishes to receive periodic updates of the LIDs to which it has subscribed, it may call this API, and it will no longer receive callbacks due to subscription updates. 

Errors returned: 

API_ERROR_AGENT_NOT_REGISTERED 

 Agent has not registered before trying to unsubscribe. Call ApiRegisterAgent() first. 

ApiGetData 

AgentApiReturnType ApiGetData(uint32_t lidNumber, ApiVariableType* lidValue ) 

This method is called for non-periodic data. Only non-periodic LIDs will be allowed to be retrieved through this mechanism. Note that only numeric LID’s are permissible through this mechanism. lidNumber is the value you want, and lidValue is a pointer to a destination for the resultant value. Can only be used to retrieve up to 64 bit values. Anything larger is not available here. It is assumed you will cast your values accordingly. 

Errors returned: 

API_ERROR_NULL_POINTER_GIVEN 

 lidValue may not be null. 

API_ERROR_SUBSCRIBE_LID_READ_ONCE 

 An attempt was made to read a lid one time that should be subscribed to instead. Read ApiGetLastInvalidLid() to get the lid that caused the error. 

Message to Server 

ApiWriteAgentDataForUpstreamSystem 

AgentApiReturnType ApiWriteAgentDataForUpstreamSystem (uint32_t featureId, char* data, uint32_t length); 
  
AgentApiReturnType ApiWriteAgentDataForUpstreamSystemWithTimestamp (uint32_t featureId, char* data, uint32_t length, uint64_t timestamp); 

Stores agent data intended for asynchronous transmission to an upstream system. This data will not be retrievable by the agent later, so this is only intended to be a method for sending data to an upstream system, and not as a method for storing of data for later use. The amount of data that can be written is limited to a fixed threshold; in the SDK this is set to 1024 bytes. 

Since the data is intended to be sent to upstream systems, a featureId is required to be saved along with the data so that data can be properly directed to Apps that are interested in that feature. Multiple entries for the same featureId, and even the same featureId and timestamp, are allowed. A featureId of 0 is invalid. 

Two different write calls are supported to allow a TimeStamp to be optionally passed in; if not provided, the default timestamp of ‘now’ will be attached to the data. 

Data will be stored for a finite amount of time, even after it has been retrieved by or sent to the upstream system; this is to provide for the possibility of being retrieved again if data was somehow lost. Data storage and rollover will be based on when stored data reaches and exceeds a data size threshold, not based on a timed expiration. For example, the oldest data associated with an agent may be rolled off when that agent’s total stored data size exceeds X MB. 

Errors returned: 

API_ERROR_NULL_POINTER_GIVEN 

 data pointer must not be null. 

API_ERROR_AGENT_NOT_REGISTERED 

 Agent has not registered before trying to store data. Call ApiRegisterAgent() before trying to save data. 

API_ERROR_DATA_TOO_LARGE 

 Agent tried to save data whose size exceeded the API-specified limits. 

API_ERROR_FEATURE_ID_INVALID 

 0 is not a valid featureId. 

API_ERROR_POLICY_LIMIT_REACHED 

 Daily data limit has been reached. 

ApiLogHistoryEvent 

AgentApiReturnType ApiLogHistoryEvent (uint32_t eventId, const char* eventData, uint32_t eventDataLength, uint32_t featureId, bool sendAsAlarm); 
  
AgentApiReturnType ApiLogHistoryEventWithTimeStamp (uint32_t eventId, const char* eventData, uint32_t eventDataLength, uint32_t featureId, bool sendAsAlarm, uint64_t timeStamp); 

This API can be used by the agent to log an event that will be sent to an upstream system. Since all events logged through this API will be sent upstream, a featureId is required, and it must not be 0. This will allow upstream systems to identify all events that apply to the feature that they are interested in. 

There are two APIs provided; one will log using the current timestamp, and the other allows overriding the timestamp used to log the event with one provided by the agent. 

The Agent SDK does not prevent frequent logging; however, agent designers should expect that the Meter API will implement some form of throttling that will prevent agents from logging a dangerous number of events. However, the Agent SDK does limit eventData to 256 bytes. 

Errors returned: 

API_ERROR_AGENT_NOT_REGISTERED 

 Agent has not registered before trying to log event. Call ApiRegisterAgent() before trying to log events. 

API_ERROR_DATA_TOO_LARGE 

 Agent tried to save event argument data whose size exceeded the API-specified limits. 

API_ERROR_FEATURE_ID_INVALID 

 0 is not a valid featureId. 

API_ERROR_POLICY_LIMIT_REACHED 

 Daily data or alarm limit has been reached. 

AgentAPIReturnType 

The following is the enumeration of the AgentApiReturnType, which is returned from most API calls, and which can be used to determine whether the API operation was performed correctly, or what went wrong if it did not. 

Name 
Value 
Description 
API_SUCCESS 
  
API_NO_LIDS_REMAINING 
We reached the end of the lid list 
API_LID_NOT_FOUND 
The requested lid was not found 
API_END_OF_LIST 
 
API_ERROR 
65536 
The LID is not returned by any method; rather, it allows the user to do “if error > API_ERROR” to do error detection. 
API_ERROR_INVALID_LID_VALUE 
65537 
  
API_ERROR_NULL_POINTER_GIVEN 
65538 
API caller provided a null pointer for a value 
API_ERROR_NO_LID_PERMISSIONS 
65539 
API caller did not have permission to access a requested lid 
API_ERROR_POLLING_FREQUENCY_ABOVE_MAX 
65540 
API caller requested too much data too frequently 
API_ERROR_TOO_MANY_DB_WRITE_CALLS_BY_TIME 
65541 
API caller tried to save data too frequently 
API_ERROR_TOTAL_DB_USAGE_EXCEEDED 
65542 
API caller has exceeded their data-saving allotment 
API_ERROR_NO_DATA_FOUND 
65543 
API caller requested a lid for which no data exists 
API_ERROR_DATA_TOO_LARGE 
65544 
API caller tried to save or send a piece of data which was too large 
API_ERROR_INVALID_SUBSCRIPTION_TYPE 
65545 
API caller provided an invalid enum value for the subscription type enum 
API_ERROR_AGENT_NOT_REGISTERED 
65546 
API caller tried to perform another call before calling ApiRegisterAgent() 
API_ERROR_BUFFER_TOO_SMALL 
65547 
API caller tried to load saved data, but the provided buffer could not stored the loaded data 
API_ERROR_SUBSCRIBE_LID_READ_ONCE 
65548 
API caller tried to read a subscription-only LID through ApiGetData() 
API_ERROR_ONE_TIME_LID_SUBSCRIBE_ATTEMPT 
65549 
API caller tried to read a GetData only LID through ApiSubscribeToPeriodicData() 
API_ERROR_WRONG_POINTER_TYPE 
65550 
API caller provided the wrong pointer type for one of the parameters to an API function 
API_ERROR_FEATURE_ID_INVALID 
65551 
API caller provided an invalid feature ID when attempting to save data or an event. 
API_ERROR_MESSAGE_SENDING_FAILED 
65552 
The provided agent-to-agent message could not be sent. 
API_ERROR_INVALID_AGENT_ID 
65553 
API caller provided an invalid agentID when registering. 
API_ERROR_INTERNAL_ERROR 
65554 
The API backend experienced an internal error when processing the request. 
API_ERROR_AGENT_ID_CONFLICT 
65555 
The provided agentID conflicts with an agent already registered / running in the system. 
API_ERROR_UNABLE_TO_CREATE_DBUS_THREAD 
65556 
A critical error has occurred in the system, and the API was unable to connect to the data provider. 
API_ERROR_FAILED_TO_SEND_OVER_DBUS 
65557 
The API is unable to communicate with the server over dbus. The server or dbus is down, or the service is being blocked. 
API_ERROR_POLICY_LIMIT_REACHED 
65558 
The Daily Agent Policy Limit was reached. This will be reset at midnight UTC.