====== Callbacks and actions ======
In [[pub:software:heartdroid:tutorials:hmr_quickstart|HMR language quickstart]] tutorial we discus what components should every HMR+ model contain.
These were: types, attributes, schemas and rules.
We mentioned briefly that attributes and rules definitions allow to specify so called **Callbacks** and **Actions**, which are integration mechanisms.
They allow to bind the HMR+ models with external data sources, or to provide a way of interaction with the user.
===== Use case =====
Go to [[pub:software:heartdroid:tutorials:hmr_quickstart|HMR language quickstart]] tutorial and read the Use case scenario,a s we will refer to this scenario in this tutorial.
The model that represents the aforementioned scenario is presented in the figure below.
{{:pub:software:heartdroid:tutorials:parking-zones-1.png|}}
Note, that to perform reasoning, one have to provide several attributes' values such as value of: day, hour, and location.
You can try running the inference by providing manually values of these attributes with [[pub:software:heartdroid:tutorials:haquna|HaQuNa]] commandline shell.
The comman for running the inference can look as follows:
java -cp haquna.jar:. haquna.HaqunaMain --model urban-helper-easy.hmr \
--tables ['parkingReminder'] --inference gdi \
--initial-state [day=mon,hour=14,location=pay_zone]
For more information on how to configure the inference process, see [[pub:software:heartdroid:tutorials:inference_config|Configuring inference process]] tutorial.
The problem here is that the values for day, hour and location can be automatically obtained from the system, we should not provide these information //by hand//.
These is what are the **callbacks** for.
You an download the model with callbacks created from {{:pub:software:heartdroid:tutorials:parking-zones-clb.zip|here}}. However, we encourage you to follow the rest of the tutorial and try to build it on your own.
Additionally, the notification to the user about whether he or she should start paying for parking should also be somehow presented to him/her, as the Linux console (or Android LogCat) is not very user-friendly tool for regular users.
This is where the **actions** comes for.
===== Callbacks =====
Callback is an entity associated with an attribute that is used to obtain the value of the attribute or to present this value to the user or to the external system.
More precisely, it is a Java class that that implements interface //Callback//.
It has a //execute// method that is run when the value of the attribute is needed.
The example of the callback is presented in the listing below. It is a callback for obtaining system time (hour):
import heart.Callback;
import heart.Debug;
import heart.HeaRT;
import heart.WorkingMemory;
import heart.alsvfd.SimpleNumeric;
import heart.exceptions.AttributeNotRegisteredException;
import heart.exceptions.NotInTheDomainException;
import heart.xtt.Attribute;
import java.util.Calendar;
public class GetSystemHourCallback implements Callback{
public void execute(Attribute subject, WorkingMemory wmm) {
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
try {
SimpleNumeric valueToSet = new SimpleNumeric((double)hour);
wmm.setAttributeValue(subject, valueToSet,false);
} catch (AttributeNotRegisteredException e) {
//handle this
} catch (NotInTheDomainException e) {
//handle this
}
}
}
To bind this callback with an attribute **hour** from our model you can modify the HMR+ code of hour attribute definition, like in the following listing:
xattr [name: hour,
type: hour_type,
class: simple,
comm: in,
callbacks: 'GetSystemHourCallback'
abbrev: hour_att
].
Alternatively, you can use [[pub:software:hwed:start|HWEd editor]] to add the callback.
==== Compile and run ====
Callbacks are loaded during runtime, hence they need to be compiled before.
Download the callback from previous section and compile it with following command (you will need to download the latest version of HeaRTDroid from [[pub:software:heartdroid:downloads:start|here]]):
javac -cp heartdroid.jar:. GetSystemHourCallback.java
After that you can run the model just as we did previously, but now **do not provide the hour** as an initial state -- it should be read automatically by callbacks system.
java -cp haquna.jar:. haquna.HaqunaMain --model urban-helper-easy.hmr \
--tables ['parkingReminder'] --inference gdi \
--initial-state [day=mon,location=pay_zone]
Try to do the same for the **daytype** attribute.
===== Actions =====
Actions are based on the same concept as Callbacks.
There are several differences though:
* Actions are associated with rules and are fired when the rule fires
* Each rule may have severl actions assigned
* Actions should implement Action interface, instead of Callback interface
* Action cannot modify the state of attributes, although have insight into the current state of the system (current values of all the attributes from the model)
To add an action to your rule, use the ''**>'' operator, like in the listing below:
xrule parkingReminder/1:
[
location eq pay_zone,
tariff eq pay
]
==>
[
notification set start_parking_fee
]
**>
[
'ShowNotification',
'StartPayment'
].#1