I want to know how to escape while using slot
for example, there is a slot need entities #time, #date, #place
so user said "next sunday, in the market"
In this moment, not include #time. so slot asked "I need time information too"
but user doesn't answer about time, just input "main menu" because he want to go main node (welcome message)
In conclusion, I wanna make when user in slot, but input other intent, just quit slot(Ignore all data from slot) and go intent node.
How can I do that? It's seem to be impossible..
As #data_henrik suggests the way to handle this is through a digression. When you hit the "I don't know what time" or : "go back to the main menu" digression, you can perform operations to break out of the slot operation.
There are a number of ways to break of slots:
You can clear the dialog stack - <? clearDialogStack() ?> which will go back to the beginning.
You could set the required time field to a temporary value; set some handling variables; then handle the redirection in a post slots node, which checks for digression set variables.
Related
Say I have STATE_A & STATE_B, both state will transit to STATE_X under EVENT_X. Now at STATE_X, when it receives another EVENT_X, I want it to go back to the previous state, e.g. if start from STATE_A to STATE_X, then it should go back to STATE_A.
One possible way to do this is to put STATE_A and STATE_B into a sub state machine, and use the history feature, but I do not want another layer of state machine.
Another possible way is to replace STATE_X with STATE_X_A and STATE_X_B, so STATE_A will transit to STATE_X_A, which will go back to STATE_A, and likewise for STATE_B. This will result in some redundent code.
What is the best way to do this using Boost MSM?
We are using Amazon Connect, Lex and Lambda to create a phone bot. One use case we have is that we need to put the user on hold while we find information in other systems. So the conversation will be something like this:
- bot: hi, what can I do for you?
- user: i want to make a reservation
- bot: wait a minute while I fetch information about available rooms
... after 5 seconds ...
- bot: I found a free room blah blah
I don't see a way to send the wait a minute... message and keep control of the conversation. How can we achieve that?
You can accomplish this inside a single Lex bot by setting the intent to be fulfilled by a lambda function, the response of the function would play a message saying “please wait” and then chain another internet to perform the search using the data from the original intent.
See this link for information about sharing data between intents.
You can chain or switch to the next intent by passing the confirmIntent dialog action back in the lambda response. See this link for more information on the lambda input and response format.
You can use wait block in aws connect https://docs.aws.amazon.com/connect/latest/adminguide/flow-control-actions-wait.html
By using this block you can set time to 5 secs . after time expired you can play prompt.
This is a very common problem typically when we want to do backend lookups in an IVR. The problem is lex does not provide any means to just play prompts.
One way to do it is:
Create a dummy slot in your intent (the reservation intent from your example above) with any type (e.g. AMAZON.NUMBER), we don't really care what the value is in this slot
From the lex code-hook for the intent, return ElicitSlot for this dummy slot with prompt as "Wait a minute while I fetch available rooms... "
If you do only this much, the problem you will face is that Lex will expect input from caller and will wait for around 4 seconds before passing control back to the Init and Validation Lambda, so there will be unnecessary delay. To overcome this, you need to set timeout properties as session attribute in "Get Customer Input" block from connect.
Property1:
Lex V2 Property name: x-amz-lex:audio:start-timeout-ms:[intentName]:[slotToElicit]
Lex Classic Property name x-amz-lex:start-silence-threshold-ms:[intentName]:[slotToElicit]
value: 10 (or any small number, this is in millseconds)
Property2:
Only available in Lex Classic, to disable barge-in on Lex V2, you can do it for required slot from lex console
Property name: x-amz-lex:barge-in-enabled:[intentName]:[slotToElicit]
Value: false
If barge-in is not disabled, there is a chance user may speak in middle of your "Please wait..." prompt and it will not be played completely.
Official documentation for these properties:
https://docs.aws.amazon.com/connect/latest/adminguide/get-customer-input.html
https://docs.aws.amazon.com/lexv2/latest/dg/session-attribs-speech.html
Another way:
Whenever such a prompt needs to be played, store the lex context temporarily either as a contact attribute after serialization, or if too big in size to be stored as contact attribute in a store like dynamodb.
Return control back to connect, play the prompt using 'Play prompt' module in connect. To give control back to bot, you will need invoke a lambda to re-initialize Lex with the full lex context again- using PostText API and then again passing control to same bot using 'Get Customer Input'
I have implemented option1 and it works well. You can even create cover-prompt which gets played if the backend lookup takes longer than expected. The actual lookup could be delegated to another lambda so that the code-hook lambda can continue doing customer interaction ever x (say 5) seconds to keep them informed that you are still looking up information.
I have a FlexRay PDU called TEMP in our case, which is getting filled in every cycle, and i would like to simulate a timeout on this PDU, but it has no updatebit.
I have a panel where i check the enable button to decide if it should be sent out or not.
frPdu FR::TEMP_Pdu;
on preStart {
if (#FR_namespace::TEMP_Enablebutton)
{
FRSetSendPDU(TEMP_Pdu);
}
}
on frStartCycle * {
if (#FR_namespace::TEMP_Enablebutton)
FrUpdatePDU(TEMP_Pdu, 1, 1));
}
Whatever I set my button to, the PDU gets transmitted every loop.
FRUpdatePDU() is not sending another instance of PDU, it is just updating the next iteration with data from the frPDU object, since we are talking about PDU of a static frame, once the VN starts sending it, you cannot stop it individually by PDU control.
Frame vs. PDU
A frame is physical Flexray Frame on the network. a PDU, is a virtualization of a part (or of the entire) of the frame payload.
Analogy: The postal truck is the FlexRay Frame, and the boxes in it are PDUs. For the Postal service (Flexray Protocol - OSI layer 1) the important unit is the truck itself, and for you (the client), the boxes in it. You will never be interested in what kind of truck delivered your goodies in a box, you are interested only in the content itself.
When you call the FrUpdatePDU(), you not only start sending the PDU, but you activate (send non-null frames) its slot also.
By setting the frame underneath to non-null frame, you ensured (in a case of static frame) that it will be sent cyclically from that point, automatically, regardless what you want to do with the PDU (the trucks are going anyway, even if you don't want to send boxes in them).
Solution:
I presume you do not have IL DLLs to aid you, therefore you are limited to the functions CANoe environment provides as General FlexRay IL functions.
You need to identify the frame carrying the PDU.
You need to manipulate the frame also with frUpdateStatFrame().
frframe FramefromDBCofTEMPPDU InstanceofFrameTemp;
on frStartCycle *
{
if (#FR_namespace::TEMP_Enablebutton==1)
{
mframe.fr_flags=0x0;
frUpdateStatFrame(mframe);
TEMP_Pdu.byte(0xAA);
FrUpdatePDU(TEMP_Pdu, 1, 1));
}
else
{
mframe.fr_flags=0x80;
frUpdateStatFrame(mframe);
}
}
So, in fact you need to modify the frame also. About the frame flags, check out the definition of the frframe in Help.
I don't use Vector CANoe or CANalyzer myself and there is almost no public documentation, so I can only offer some general debugging hints:
Have you checked that #FR_namespace::TEMP_Enablebutton has the expected value, i.e. that it is really false when you turn the button off? You could add a write() before the if() inside "on frStartCycle" to check this.
This question looks similar: Sending Periodic CAN signals on button press using CAPL and CANalyzer - they use "on sysvar" to react to the button press, maybe you have to do something similar. Namely: React to the button press, set an environment variable, check that variable in "on frStartCycle"
Since there is not a lot of public documentation, you can also try asking around inside your company, there might be some people around you who can help you.
The MSDN documentation says that the LParam first 15 bits is used for repeat count , but it says that it is not accumulative
Now unless i am missing something here, why does it call it a repeat count but says it is not accumulative?
This is an oxymoron statement? It says it does but it doesn't? Or am i missing something here?
I Actually tested it and masked it with bitwise operator to extract those first 15 bits with LParam&0xFFFFand no matter how much i hold down the key , this value remains as 1
Unless i am doing something wrong or missing something, i dont know what is the point of this counter which doesnt count? Or am i misunderstanding something and doing this the wrong way and there is something that needs to be done to use this
It would be much more effective and convenient to have this counter so that i dont have to run all this other code to count the repeat count for the keys pressed and held , so is it possible to be done using those first 15 bits? maybe increment those first 15 bits?
Lets start at the documentation:
The repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key.
This part is relatively straight forward. The repeat count field is the number of 'presses' the key had.
If the keystroke is held long enough, multiple messages are sent.
Multiple messages can be sent, depending on your message loop. Windows will keep sending you messages as long as the key is down, so you can keep processing repeats.
However, the repeat count is not cumulative.
The repeat count doesn't carry over between messages. In other words, each message represents the number of repeats since the last time you processed a WM_KEYDOWN message.
The reason you never see a repeat count above 1 is that you're processing window messages too quickly. You can see higher numbers by putting a delay into your WM_KEYDOWN message handler to allow more repeats to queue into the next message. (In C# here because there's less boilerplate code, but you should be able to translate it to whatever language you use.)
private const int WM_KEYDOWN = 0x0100;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_KEYDOWN)
{
System.Threading.Thread.Sleep(1000);
this.Text = $"Keydown Count: {m.LParam.ToInt32() & 0xFF}";
}
base.WndProc(ref m);
}
Running this code, I see repeat counts near 20-30.
If you need the total number of repeats, you will need to keep a running tally from the first WM_KEYDOWN until the WM_KEYUP. The design is so that you can process the events as they come in. (Picture a text box: responsiveness demands that you process the keys as they come in, rather than wait till the key is released.)
I want to link two different WoW events together. I need some information from both events and store them together in a simple table. Also it is important that the data of the second event is stored only if the first event even fired!
In my case its the name of a creature from COMBAT_LOG_EVENT_UNFILTERED and the reputation gained from COMBAT_TEXT_UPDATE. The reputation should only be stored, if it is gained from killing a creature. I am currently doing that with a temporary table to link those. It stores the name from the first event and will be readable in the second event. Here's the simplified code for that:
nehFragger_ReputationDB = {} -- The actual database for my AddOn.
local tempKillLog = {} -- A table that I use to link the different events.
function nehFraggerFrame_OnLoad(frame)
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
frame:RegisterEvent("COMBAT_TEXT_UPDATE")
end
function nehFraggerFrame_OnEvent(frame, event, ...)
local arg1, eventType, arg3, arg4, sourceName, arg6, arg7, destGUID, destName = select(1, ...)
if (event == "COMBAT_LOG_EVENT_UNFILTERED") then
if (eventType == "PARTY_KILL") then
tempKillLog.creatureGUID = destGUID -- The unique identifier of the creature.
tempKillLog.creatureName = destName -- The creature name that I need.
end
end
local eventType, faction, reputation = select(1, ...)
if (event == "COMBAT_TEXT_UPDATE") then
if (eventType == "FACTION") then
local GUID = TempKillLog.creatureGUID
if (string.upper(string.sub(GUID, 1 , 8)) == "CREATURE") then -- Make sure the link-table data really is a creature.
local creatureName = tempKillLog.creatureName -- The name from my link-table.
local reputationGain = reputation -- The reputation that I need.
-- Simply store the stuff to the database table for this faction:
nehFragger_ReputationDB[faction] = {}
nehFragger_ReputationDB[faction].creatureName = creatureName
nehFragger_ReputationDB[faction].reputationGain = reputationGain
end
end
end
end
This works...sort of. There are several problems with that (see below).
My question here is:
Is there a possibility to either
- get some unique identifier for the source of different events in general (like the destGUID of COMBAT_LOG_EVENT) to connect those
- or is there an even simpler way to get the reputation of a kill (including creature and reputation information) like in the case of my AddOn?
Some more things to consider:
I have also tried to use the current time in both events to check if these are fired within say 0.01 seconds. That erases loads of problems I have encountered, but will still fail in certain circumstances. If, for example, you finish one of these new Legion world-quests by killing a creature and then gain the reputation for the quest itself. That's still within the timeframe, regardless of how small it is.
Another problem is, if you kill more than one (say 5) creature at a time, then the first event COMBAT_LOG_EVENT_UNFILTERED first fires 5 times in a row, and THEN the second event COMBAT_TEXT_UPDATE fires 5 times. In this case, all the 5 logs in my nehFragger_ReputationDB have the correct amount of reputation gained but all of them with the name of the last creature killed/processed...
I would really like to use the GUID for both events to link them, but I cannot get the one of the second event - if there even exists one. That would be the cleanest and safest way in my opinion.
Or, like already mentioned, a dedicated WoW event for this. But I didn't find one.
I hope somebody can help me here or provide some food for thought.