pebblekit js send array to pebble C by appmessage - c

I am trying to code my first Pebble C app which is based on a pebble.js app I made. I am basically showing the bus schedules.
My question, How can I pass the information from pebblekit js to the pebble C by appmessage so that I can construct a menu? how can I pass an multiple dimension array by appmessage to the watch?
here is an example of the json my pebblekit js has to send to the watch:
{
"buses":[
{
"bus_number":"55",
"stops":[
{
"stop_id":"109698",
"stop_times":[
{
"arrival_time":"21:22:25",
"departure_time":"21:22:25"
},
{
"arrival_time":"21:52:25",
"departure_time":"21:52:25"
},
...
]
},
...
}
}

Unfortunately there is no way to send an array natively. This is the general framework of how I go about it in my apps. I won't post code because it varies depending on the project.
Add the MessageQueue library to your project. This library is great for sending lots of data at a time or many different pieces quickly.
Create a sendArray function which simply loops through each of the objects in the array and sends them to Pebble with MessageQueue.sendAppMessage()
On the C side, in your inbox handler, check for a certain key which you expect to be sent with the array object. For example, if each array object has a temperature key in it, check for that key and then you'll know the rest of the data should be there too.
3.1. Insert all of this data you just got on the C side from the DictionaryIterator into some sort of struct which you have created to represent the array item.
3.2. After processing all of that data, insert that updated struct into an array.
Keeping a stack count for that array is usually a good idea too.
Let me know if you need any more help or if I can explain anything better.

Related

Firebase: Storing multiple strings inside an array of the same data

I'm making a scheduling app, and storing all the scheduled things in firebase with arrays. When I try to schedule something with the same string value, it fails and doesn't add it to the array. I don't know if this is something in swift I can edit, or if it's a firebase setting.
If it's something in swift, here's the code updating the array:
doc.updateData([
"Instructor": FieldValue.arrayUnion(["\(scheduleinstructor)"])
])
If it's something in firebase, could someone please explain a way around this or a simple fix I overlooked?
According to the documentation on adding items to an array:
arrayUnion() adds elements to an array but only elements not already present
So the fact that the duplicate entry is not added is by design. If you want to allow that, you'll have to:
Read the document with the array from the databae.
Extract the array from the document into your application code.
Add the item to the array.
Write the entire modified array back to the database.

MFC MDI CMFCPropertyGridProperty adding Array for dropdown list merging MP4 tag data

I need some guidance on how to add a drop down list from an array of data after the read info from the MP4 Tag data is parsed. The mechanism I'm using is 100% operational, this is a creature feature addition. The MP4 tag I'm working with is Genre using the ID3V1 standard. There are 191 choices. The way my app was inherited, there are 2 columns, property/value and multiple rows. All of that works. The Genre tag was setup willy nilly so you could basically type whatever and it would store it. I want to remove that and have the 191 elements in the array to choose from using the drop down list. Part of the loading process is that it will pull in whatever was in the MP4 file. So, I want the user to be able to leave as is (most likely tagged by something that supports ID3V2), or select from the populated 191 elements in the dropdown list.
The object looks like this information.h:
protected:
CMFCPropertyGridCtrl m_wndProperties;
The information.cpp looks like this:
void CInformationView::OnInitialUpdate()
{
// create property grid
VERIFY(m_wndProperties.Create(WS_CHILD|WS_VISIBLE|WS_TABSTOP| WS_BORDER, CRect(0,0,0,0), this, 0));
// get document
CMovieDoc *lpkDoc = GetDocument();
ASSERT_VALID_PTR(lpkDoc);
// add properties //Information ORDER Loading <<<<< List shortened Stack overflow question
m_wndProperties.AddProperty(lpkDoc->m_pkArtist);
m_wndProperties.AddProperty(lpkDoc->m_pkTempo);
m_wndProperties.AddProperty(lpkDoc->m_pkGenre);
CView::OnInitialUpdate();
}
The way it pulls the data in from mp4.cpp:
// Genre
m_pkGenre = new CMFCPropertyGridProperty(_T("Genre"),
COleVariant(AfxStringFromUtf8(lptTags->genre), VT_BSTR));
The pointers in mp4.h:
CMFCPropertyGridProperty *m_pkArtist;
CMFCPropertyGridProperty *m_pkTempo;
CMFCPropertyGridProperty *m_pkGenre;
Now I know that pull downs in the 2nd column (Values) can be done because other tags have simple TRUE/FALSE that can be selected, so that tells me it should be possible to create the drop down list I'm looking to do. An example of the TRUE/FALSE looks like this:
// Compilation
m_pkCompilation = new CMFCPropertyGridProperty(_T("Compilation"),
COleVariant((!VALID_PTR(lptTags->compilation)) ? (short)0 : (short)*lptTags->compilation, VT_BOOL));
I've done arrays in C for things like microcontrollers, but not entirely sure if it is the same in C++. I'm thinking it should look like this:
// Initialize Genre Array
const char *genre[4] = { "Rock", "Rap", "Soul", "House" };
The questions are:
How do I create an the array (or does my example above look correct?) to house fixed strings like "Rock", "Rap", "Soul", etc. etc?
How to modify the VALUE row to have the pull down that contains the parsed Genre tag present and then when opened, show the 191 Genre tags where one can be selected to choose from (and ultimately save which is already working).
Actual code, not references to the learn.microsoft.com, the few things I've tried crashes when I try to alter the AddProperties I assume because of the lpkDoc pointers being used.
You should not use a plain old C-style array if you do not have a strong reason to. Use a std::vector instead. You don't even need to indicate the [size].
The same goes for char *. Use a CString or astd::string instead.
const std::vector<CString> = { L"Rock", L"Rap", L"Soul", L"House" };
Don't make your life harder than it needs to be.
2.
for (size_t i= 0; i < genre.size(); i++)
{
auto gnr= genre[i];
lpkDoc->m_pkGenre->AddOption(gnr);
}
or even better
for (auto it : genre)
{
lpkDoc->m_pkGenre->AddOption(it);
}
Important note: You should not have code about properties in your doc object. You are mixing business logic with user interaction logic. Your code in the future will be a nightmare to maintain.
I do not see your lpkDoc->m_pk variable init'ed anywhere, and I bet those pointers are pointing to no man's land.

How to sample random numbers in Watson Assistant?

I'm using IBM Watson Assistant for creating a chatbot. I'm using the web interface with the intents, entities and dialog flow|tree (I don't know how it is called, I'm just calling it web interface).
I would like to define an array of the numbers [1,2,3,4,5]. Then one node should sample a random number without replacement from that array (e.g. 2), i.e. the remaining array is then [1,3,4,5]. After some time another node should pick another number at random from the array (say 4). And so on. How can this be implemented? I know about variables (e.g. $var) but I don't know how to represent arrays and sample random numbers.
Thank you so much for your answers in advance. And happy new year to everybody.
As a general rule about what might be possible we use the doc for the Spring Expression Language. Based on that, you could select a value from some data structure $some_array like this:
{
"context": {
"randomNumber": "<? (new java.util.Random().nextInt($some_array.size())) ?>"
}
}
After that, you access your value using
{
"context": {
"element": "<? $some_array.get($randomNumber) ?>",
"shorter_array": "<? $some_array.remove($randomNumber) ?>"
}
}
Now there are some issues (probably the bug mentioned in the comment), as the remove method should be the one from the gson JsonArray and behave like this:
Removes the element at the specified position in this array. Shifts any subsequent elements to the left (subtracts one from their indices). Returns the element that was removed from the array.
However, it returns the array with the element removed, not the element itself.
1) In your Dialog Node, define slots
2) In the first one, generate the random value (if array defined and not empty)
3) In the second, get the element and remove
Note, that even though this works, you should probably not use it in a production version of your Chatbot. Instead, put most of the logic in your application (including the control of the dialogue). The Web Interface is very difficult to test and the way the variables are parsed might change at some point.

Access Lua variables in userdata from the C api

I am working on a project written in C++ which uses Lua as a scripting language.
In order to facilitate debugging we implemented a network debugger which receives Lua code, runs it, encodes the return values in Json and sends that string back.
I managed to implement that for tables, but now I am stuck with variables stored in userdata.
E.g. I have this Lua code:
Elements.Avatar.testVar = 5
Elements.testVar = 15
return Elements
// result
{
"result0": "{Application:userdata; Avatar:userdata; Physics:userdata; testVar:15; }"
}
Application, Avatar and Physics are objects that have been created in C++. The two testVars however have been created in the script above.
Elements is a table, so I can list all elements, but Avatar.testVar seems to be hidden because Avatar is a LUA_TUSERDATA.
Does anyone have an idea how I can detect variables that have been added to userdata in Lua?
There is no such thing as a "variable stored in userdata", At least, not as far as Lua is concerned. From Lua's perspective, userdata is a giant black box. All Avatar.testVar = 5 does is call the metamethod __newindex in Avatar with the string testVar and the new value 15. How your C++ metamethod (because only C++ code can put metamethods on userdata) interprets this is entirely up to your code.
So it can't be done from Lua. Your code will need to provide debugging hooks. Lua 5.2 allows you to implement the __pairs and __ipairs metamethods, which the pairs and ipairs functions can use to iterate over your values. Outside of that, you're on your own for querying what does and doesn't exist in a userdata.

quering for objects with angularFireCollection?

I used the implicit method for retrieving data objects:
setData = function(segment){
var url = 'https://myFireBase.firebaseio.com/';
var rawData = angularFire(url+segment,$rootScope,'data',{});
rawData.then(function(data){
// sorting and adjusting data, and then broadcasting and/or assinging
}
}
This code is located inside a service that gets called from different locations, by development stages it'll probably be around 100 - 150 so I got out of the controllers and into a service, but now firebase data-binding would obviously over-write the different segments so I turned back to explicit methid, to have the different firebases only sending the data to site instead of data-binding and over-writing each other:
var rawData = angularFireCollection(url+segment);
And right there I discovered why I chose the implicit in the first place: There's an argument for the typeof, i could tell firebase if I'm calling a string, an array, an object etc. I even looked at the angularfire.js and saw that if the argument is not given, if falls back to identifying it as an array by default.
Now, I'm definitely going to move to the explicit method (that is, if no salvation comes with angular2.0), and reconstructing my firebase jsons to fit the array-only policy is not that big of a deal, but surely there's an option to explicitly call objects, or am I missing something?
I'm not totally clear on what the question is - with angularFireCollection, you can certainly retrieve objects just fine. For example, in the bundled chat app (https://github.com/firebase/angularFire/blob/gh-pages/examples/chat/app.js#L5):
$scope.messages = angularFireCollection(new Firebase(url).limit(50));
Each message is stored as an object, with its own unique key as generated by push().
I'm also curious about what problems you found while using the implicit method as your app grew. We're really looking to address problems like these for the next iteration of angularFire!

Resources