Ask for missing DB data with Alexa - amazon-web-services

I'm trying to do the following with Alexa:
When a user say: open APP_NAME
I'm checking the DynamoDB to see if I have the name of the suer
if not I'd like to ask for the name before I tell what the app can do
I did try to use
this.emit(":delegate", "name_add");
From the Intent that is triggered when you say "open APP_NAME", this means that in the Hello intent I make a query, check if I have the name, and if not I'd like to trigger another Intent to get the missing data.
But when I use Delegate, the "name_add" intent is not being triggered.
My questions
When I'm in one intent that relies on data from the DB, and I see that there is data missing, how should I go about collecting this missing data? Mind you, once this data is in the DB I won't ask the user about it. So it is a one time thing.
Meaning I know how to take advantage of slots, when you ask for example from where are you flying to where. Because this is something that Alexa will ask each time. But what when you need to do this one time?

The problem is, you cannot delegate to a new intent. Read about Dialog Directives here.
Note that you cannot change intents when returning a Dialog directive, so the intent name and set of slots must match the intent sent to your skill.
So you are going to have to restructure your intents.
Suggested Structure:
Normally, your helloIntent (when the user opens your skill 'naked': "Alexa, open mySkill." instead of 'with clothing': "Alexa, open mySkill and do something"), this is when you want to direct the user into saying what to do that will trigger your main intents.
So the helloIntent will simply respond with: "Hello, welcome to mySkill, you can say things like, do something, or, do something else"
The user then says one of those things, which is an utterance of your other intents, therefore triggering one of those intents, lets call one: "checkDatabase".
Now that you are inside of "checkDatabase" intent, you can have a required slot called name. This is when you can check the DB for a user's name and fill the slot yourself, or delegate back to Alexa to elicit name.
Things to know:
1) Delegate only works with required slots of the intent. You are delegating to Alexa to figure out what slots are needed to be filled and which to elicit first. She figures this out based on the order of the required slots you have set up for the intent in the Console.
2) this.emit(':delegate', updatedIntent); (using the Alexa SDK) needs the second parameter updatedIntent to be an object of the full intent information which includes the name, slots and confirmationStatus (see Intent Object here). If you fill slots yourself, this is how you return the 'updated' intent information.
3) For more control in which slots to elicit and with a specific message, use ElicitSlot Directive.
Which in the Alexa SDK is: this.emit(':elicitSlot', slotToElicit, speechOutput, repromptSpeech, updatedIntent) Read about that here.
(ElicitSlot must be used to elicit unrequired slots)

Related

cfapi: CfDehydratePlaceholder seems to be stucked

My target is, that files can be hydrated or dehydrated on user request via the Explorer "free up space" or "Always keep on Device" ContextMenu entry. In case I create a new placeholder file that is dehydrated from the beginning, everything works and I can hydrate it via the callback mechanics. But the way around does not work for me. Inside of the Explorer the file will be marked as UnPinned and the file will be marked as syncing, but my application does not receive any callback from CF_CALLBACK_TYPE_NOTIFY_DEHYDRATE or CF_CALLBACK_TYPE_NOTIFY_DEHYDRATE_COMPLETION. Then I wanted to do it manually with CfDehydratePlaceholder, but exactly the same behaviour. Nothing happens and the file remains in the state, syncing. Even if I used CfSetInSyncState to set the state to CF_IN_SYNC_STATE_IN_SYNC it remains to be in the state syncing.
Now I wanted to implement a minimal example with the help of Cloud Mirror Example, but I realized it has the same behaviour. When I try to dehydrate a file again exactly the same happens there as well. From my perspective, it feels for me like cfapi expects an ack from the cloud service, which it never gets.
But in OneDrive everything works like expected. What I am missing? Did I have to set some specific settings?
I had a misunderstanding of the whole API and here is how I understand the API now, to help other people, who are struggling with it.
You have to register your sync root and connecting your app to it. In case of connecting it, you will receive a CF_CONNECTION_KEY, which is needed to communicate with the virtual filesystem. Then you can add extended attributes to all files inside of your sync root. The most important are custom attributes you can choose by yourself to identify the file object by your app if needed and then the PinState and SyncState. Mostly the SyncState don't have to be changed by the app, besides marking a file as synced after it was processed by the app. (you can do it at the moment you update your custom attributes) Because in case a file changed, the SyncState will automatically be changed. The PinState declares which final state a file should have. For example UNPINNED means, that the file should be dehydrated, and PINNED the opposite. It does not mean, that the file necessarily has already this state. My misunderstanding was, that I thought in case I unpinned a file, it will be automatically dehydrated. Or in case I pinned a placeholder I will receive a request via the callback function I mentioned in my question. But this is not the case. Your app needs to find out via a FileWatcher (i can recommend my own created FileWatcher project: https://github.com/neXenio/panoptes) that the file attribute of specific files was changed. Then your app has to process every step. Like already mentioned in case of dehydrating, the app needs to call CfDehydratePlaceholder. In case of hydrating, you need to open a transfer session via CfGetTransferKey and then hydrate (send the data to the empty file) via the method CfExecute, where you need the connection key and the transfer key. And that's are the basics. There is much more to tell about it, but I guess with this beginning, everybody can figure it out by himself.

How to ALTER CHANNEL in C++?

IBM's documentation on ALTER CHANNEL goes to commendable length explaining the various available alterations, but does not offer a single example -- certainly not for C++-users.
Suppose, I want to change the MCAUSER from the default (OS username) to another string, what would the function-call look like?
The documentation you link to in your question is the MQSC command reference. This is designed for scripts.
Please also note that the default value of a channel's MCAUSER field is actually blank, not the OS username. Because it is blank, then in the case of a SVRCONN channel, when a client application connects, the OS username flowed from the client, will be used for the MCAUSER for that running instance. You cannot change this behaviour using ALTER CHANNEL from your client application. I note this, in case this is the reason you are thinking to use ALTER CHANNEL.
If you want to write a program to make a change to an IBM MQ object, such as a channel, you would instead want to make use of a different, but equivalent interface called the Programmable Command Format (PCF). The equivalent command reference page is here.
There is an example C++ PCF sample here - look for SrvPCF
In short, psuedo-code, you would write a program as follows:-
MQCONN(Qmgr-name)
MQOPEN(Reply-Q)
Build PCF message for MQCMD_CHANGE_CHANNEL
with MQCACH_CHANNEL_NAME
with MQIACH_CHANNEL_TYPE
with MQCACH_MCA_USER_ID
MQPUT1(PCF Message to SYSTEM.ADMIN.COMMAND.QUEUE)
MQGET(wait for reply on Reply-Q to say whether it worked or not)

How can I add a new message in the mavlink protocol?

I'm new in Mavlink, I want to add a new message in the Mavlink protocol and send it each second periodically. How can I do it?
Here you can find detailed steps about how to add new message to mavlink protocol and how you handle it.
Ensure you have the latest ArduPilot code and Mavproxy installed.
Decide what type of message you want to add.
Add the new message definition to the common.xml or ardupilotmega.xml file in the mavlink submodule.
Add functions to the main vehicle code to handle sending or receiving the command.
It depends on what autopilot you are using. If you're using ardupilot then you would need to add a new xml message definition in ardupilot/modules/mavlink/message_definitions/v1.0/ardupilotmega.xml.
You can look at the other messages to see how it should be formatted. Just make sure you choose an id that is unused.
Next you need to decide how to put this in the code. You could place it in the data_stream_send task by adding the message id to, say, STREAM_EXTRA3. This will send your message as often as the other data is sent there. As part of that you will need to define the function to actually pack your data structure using the function generated by pymavgen, the message id and enumerations. This is what I have done in my own project for ASH_DATA. You can see the changes I've made in my repository for reference. Note that some of those include changes to incorporate reception of ash data on the pixhawk and adding the data to a log file.
Given that you want to run this once a second you may want to add to the one_second_loop task or create your own task that simply calls the try_send_message function using your new message id.
You will of course need to incorporate the new message in your gcs so you can actually receive it, but that's another matter.
Hopefully this can nudge others in the right direction who are trying to do the same.

Calling a function after another function is called

I'm programming a controller for use with Ableton Live 8 using the Python-based API. In my code I use a method provided in the API to watch for changes in a property's value, and call a function whenever the value changes. My goal is to change the color of the clip when the value change is noticed.
I have my code completed, and it compiles without error. From Ableton's log:
742234 ms. RemoteScriptError: RuntimeError
742234 ms. RemoteScriptError: :
742234 ms. RemoteScriptError: Changes cannot be triggered by notifications
742234 ms. RemoteScriptError:
It appears this is the result of using the built-in notification system to make a change to the live set during notification. Triggering the actual change AFTER the listening function has finished executing should work. Is this possible using Python?
Edit for clarification:
currently we have
value change noticed, function called
function attempts to change the clips color (results in error)
we need
listener notices value change, function called
function finds the new color value
function execution ends
another function is called outside the listener's scope, and changes the clips color
I did a lot in M4L and know this error by heart :)
I'm afraid you can't do anything about that - to my noob eyes it looks like a built-in security mechanism so you can't loop (Something changed? Change it! Something changed...).
In M4L i used Javascript Tasks to separate the steps (Tasks forget nearly everything),
something like
Observer -> Something changed
Create a Task that reacts
task.execute() or task.schedule(time)
Maybe the python threading module can achieve something similar?
BTW, if you happen to understand anything about the _Framework-Tasks, let me know.
I was having the same issue trying to delete a track from a clip stop listener, then I found this thread and followed #user2323980 suggestion.
There seems to be a "_tasks" object on every Framework class (I found it throught log_message inside ClipSlotComponent and ControlSurface) that handles concurrency between tasks. And it's really simple to use it:
self._tasks.add(Task.run(func, args))
I found some uses of it on Push and MK2 scripts, those are good references.

Qt QApplication::commitData, Windows shutdown, confusing documentation

I'm quite confused as to what should and should not be done in QApplication::commitData. The name implies that I should just store the state, and the docs say it should not close the application. However, the default implementation indeed closes all windows thereby closing the application. Also, if this is not the way to detect windows shutdown, I don't see any other way to tell that windows is indeed being shutdown.
There is also the related saveState. The function name means about the same and the documentation is also quite similar.
How am I supposed to properly detect when the system is being shutdown and both save my state and close my application? Is commitData indeed the correct way and just suffering from a very poor name and bad documentation?
In my practice to detect an application shutdown I usually connect to the slot void QCoreApplication::aboutToQuit (). As it says in the docu:
The signal is particularly useful if your application has to do some last-second cleanup. Note that no user interaction is possible in this state.
So far so good this has worked for me properly
commitData() and saveState() may seem redundant.
But the documentation
says
Futhermore, most session managers will very likely request a saved state immediately after the application has been started. This permits the session manager to learn about the application's restart policy.
Maybe that explains why the notion of 'data' and 'state' are separated. During that initial call, it would not be user friendly to interact with the user.
The default response to shutdown the application seems like a good design, because if you don't reimplement, then the safest thing to do is to close the app (as if the user had chosen the Quit action), which should also save the user's data.
Is the OS shutting down, or only the session? As far as your app should be concerned, it is only the session (since technically, the user could be logging off and the OS continues to run.) And the user might consider the app to be not 'shut down', just 'paused with data safed.'
Also consider mobile platforms like iOS, where an application seeming runs forever.