Community Tip - You can change your system assigned username to something more personal in your community settings. X
The AddStreamEntries snippet does not offer too much information, except that it needs an InfoTable as input.
It is however based on the InfoTable for the AddStreamEntity service.
To use the AddStreamEntries table, an InfoTable based on sourceType, values, location, source, timestamp and tags must be used.
In this example, I started with a new Thing based on a Stream template and the following DataShape:
This DataShape must be converted into an InfoTable with is used as the values parameter.
It's important that the timestamp parameter has distinct values! Otherwise values matching the same timestamp will be overwritten!
We don't really need the sourceType as ThingWorx will automatically determine the type by knowing the source and which kind of Entity Type it is.
I created a new MyStreamThing with a new service, filling the InfoTable and the Stream.
The result is the following code which will add 5 rows to the Stream:
// *** SET UP META DATA FOR INFO TABLE ***
// create a new InfoTable based on AddStreamEntries parameters (timestamp, location, source, sourceType, tags, values)
var myInfoTable = { dataShape: { fieldDefinitions : {} }, rows: [] };
myInfoTable.dataShape.fieldDefinitions['timestamp'] = { name: 'timestamp', baseType: 'DATETIME' };
myInfoTable.dataShape.fieldDefinitions['location'] = { name: 'location', baseType: 'LOCATION' };
myInfoTable.dataShape.fieldDefinitions['source'] = { name: 'source', baseType: 'STRING' };
myInfoTable.dataShape.fieldDefinitions['sourceType'] = { name: 'sourceType', baseType: 'STRING' };
myInfoTable.dataShape.fieldDefinitions['tags'] = { name: 'tags', baseType: 'TAGS' };
myInfoTable.dataShape.fieldDefinitions['values'] = { name: 'values', baseType: 'INFOTABLE' };
// *** SET UP ACTUAL VALUES FOR INFO TABLE ***
// create new meta data
var tags = new Array();
var timestamp = new Date();
var location = new Object();
location.latitude = 0;
location.longitude = 0;
location.elevation = 0;
location.units = "WGS84";
// add rows to InfoTable (~5 times)
for (i=0; i<5; i++) {
// create new values based on Stream DataShape
var params = {
infoTableName : "InfoTable",
dataShapeName : "Cxx-DS"
};
var values = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params);
// add something to the values to make them unique
// create and add new row based on Stream DataShape
// only a single line allowed!
var newValues = new Object();
newValues.a = "aaa" + i; // STRING - isPrimaryKey = true
newValues.b = "bbb" + i; // STRING
newValues.c = "ccc" + i; // STRING
values.AddRow(newValues);
// create new InfoTable row based on meta data & values
// add 10 ms to each object, to make it's timestamp unique
// otherwise entries with the same timestamp will be overwritten
var newEntry = new Object();
newEntry.timestamp = new Date(Date.now() + (i * 10));
newEntry.location = location;
newEntry.source = me.name;
newEntry.tags = tags;
newEntry.values = values;
// add new Info Table row to Info Table
myInfoTable.rows = newEntry;
}
// *** ADD myInfoTable (HOLDING MULITPLE STREAM ENTRIES) TO STREAM
// add stream entries in the InfoTable
var params = {
values: myInfoTable /* INFOTABLE */
};
// no return
Things["MyStreamThing"].AddStreamEntries(params);
To verify the values have been added correctly, call the GetStreamEntriesWithData service on the MyStreamThing
EDIT: I was able to solve the problem by creating a DataShape Thing containing [location, source, sourceType, tags, timestamp, values]. Instead of defining the InfoTable object at the top, I used the CreateInfoTableFromDataShape(params), like it does in the middle of the code.
Hi Michael;
This code example has been quite helpful in explaining how to use the AddStreamEntries() service. I have seen very few examples of it, and I've had to go away from the AddStreamEntry() service due to unreliability to process the quick, looping calls that are being done while parsing a file. I have implemented your logic in a few different places, however, following the same logic in each service implemented, one of them has an error that I cannot resolve:
- Wrapped java.lang.Exception: Unable To Convert From org.json.JSONObject to INFOTABLE
The blocks of logic that are implemented in each of my services includes the following:
Creating the high-level InfoTable that will be used in the AddStreamEntries() call
Create a JSON Object that stores the stream-data we will be storing, Create an InfoTable, add the Object to the table, Create a JSON Object for the stream metadata, and add the Object to high-level InfoTable from above
And finally, call AddStreamEntries() with the high-level InfoTable that has been expanding throughout the looping process
These core features are present in three other Services, and those all work great. However, the last Service gives the JSON-to-InfoTable conversion error. I have tinkered with using some different calls, including FromJSON(), but have not had any luck.
The dsUtilizationDetails datashape does not have any Primary Key on it, and matches the "values" Object() being created in the code.
Any help you can provide would be appreciated.
Regards,
Cody
Hi Cody,
yeah, CreateInfoTableFromDataShape should work fine as well.
There are more methods of creating the initial InfoTable. In the end it's good to know that you got it working
I don't see any typo etc. in particular that could cause the error for the mainInfoTable definition.
Just a comment on the timestamp... I multiplied the i variable with 10.
I had to do this, to make the milliseconds unique - sometimes when not multiplying the code is so fast that there are two or more entries with the same millisecond timestamp. This only persists one record into the Stream.
So in case you're missing some of the entries, just increase the time difference - that should help.
Cheers,
Michael
I tried using the above service. It executes properly, but I am unable to see any added entries with GetStreamEntriesWithData.
Hello
I followed your example to adapt it to my need (it is exactly what I was looking for) .
everything seems OK (no error in logs, service well executed) but impossible to see the values using GetStreamEntriesWithData or using the mashup grid of the stream thing.
I redo the same exercice with exactly your example but still nothing logged.
An idea where I should looking for ?
I solve the issue by using AddStreamEntry() instead and following the snippet to code