MLContext QoC Tutorial v1.0 by José R. Hoyos 6th, January, 2016 1 This tutorial explains the use of the Quality of Context (QoC) modeling extension of MLContext. This extension has been designed to allow developers to define quality parameters and quality requirements for their context models. This tutorial assumes that you are using Eclipse (version v3.4+ ), and you have previously installed the MLContext plug-in updated to v1.1 (and the MOFScript plug-in if you want to generate code from the context model). The MOFScript and the MLContext plugin can be installed and updated from the MLContext update site. For obtaining information about installing the MLContext plug-in, you can read the "download and install" section in http://modelum.es/MLContext The examples of this tutorial have been tested using Eclipse Kepler , Java 1.6 and MOFScript 1.3.4. It is recommended to first read the MLContext tutorial on context modeling available at http://www.modelum.es/MLContext/documentation.htm Case study scenario To illustrate the MLContext QoC modeling capabilities, we will use a case study from [Chabridon et al., 2013] that is used to explain how QoC is managed with the COSMOS framework [COSMOS reference]. We will also explain how COSMOS code can be automatically generated from MLContext models which have a higher level of abstraction and are more readable. A user (Celina) has a smartphone so it is possible to use its location services. These location services are based on not only GPS navigation but also 3G and Wifi communication. She has downloaded a flash sale application in her smartphone to receive a notification whenever a flash sale offer is near her that matches her preferences. Depending on the quality level of the reported location for Celina, she receives more detailed indications on how to reach the shop. GPS GPRS User Celina Shop Smartphone The location of the user can be provided by several sensors (GPS, GPRS and Wifi), which has different QoC properties. For this scenario, three QoC parameters are considered for the location property (accuracy, freshness and trustworthiness). 2 Three QoC levels are also defined (high, medium and low) as follows: QUALITY_HIGH : freshness >= 0.8 accuracy < 10 trustworthiness >= 0.9 QUALITY_MEDIUM : freshness >= 0.8 accuracy < 10 trustworthiness < 0.9 QUALITY_LOW : freshness < 0.8 accuracy < 10 trustworthiness < 0.9 In order to promote the reuse and the evolvability of the models, MLContext applies a separation of concerns to build platform and application-independent context models. This is achieved by representing the application-specific details (e.g quality constraints or technical details of the sensors) into application models separated from the context model. Therefore we will create first a context model for the scenario and then a separated application model which contains the quality parameters and quality requirements for the application. The application model will include references to the elements defined in the context model. Creating a new project First of all we will create a project in Eclipse for our context model. In this case, we will create a Generic Project named "Tutorial-2" Menu File -> New -> Project... and then, we choose a General Project 3 We press the Now we can press the button and then we can enter the name of the project button to create the project The newly created project appears in the package explorer. The next step is to create a file for our context model, named "Flash_sale.mlctx". Select the "Tutorial-2" folder and press the right button of the mouse to bring out the pop up window, and then select New -> File 4 Enter the name of the file Press the button and the new file will open in the editor window. It is strongly recommended that you have the Problems and Properties tabs views open on your editor in order to check the syntax errors, and to see the values of the properties of your context model (see Tutorial on context modeling). Now, we have the file ready for writing our context model. Writing the context model We will create a contextModel named flash_sale with some entities. contextModel entity entity entity } flash_sale { Celina context {} smartphone context {} shoeShop context {} We have specified three entities: the user Celina, her smartphone and one shop that will be used to test the "flash sale alert" context situation. Next we specify some properties for the entity Celina. We are interested in knowing her location, her preferences and the fact that she carries her smartphone. The application will know that the location of the user Celina is the same of the smartphone only if the user carries it. contextModel flash_sale { entity Celina context { environment {"location" source historic} personal {"preferences" source "carrying" : smartphone}} entity smartphone context {} entity shoeShop context {} } We have specified that the "location" property is of environment type (see Tutorial on context modeling for a list of context types). We have also specified the historic modifier for the property, because we want to keep a trace of those values (they can be used to compute the speed of the user). The source keyword indicates that the value of the property is obtained from a source of context (that will be specified later in the model). We don't need to specify any properties for the smartphone in this example. Finally we define some properties for the shoeShop entity: its location and the current saleOffer (if any). entity shoeShop context { environment {"location" : "37.607602, -0.975380" units : "WGS84"} computational{"saleOffer" source}} The value for the property "location" is expressed in WGS84 units 5 Now, we can model the context sources for the properties that have been attached to a source (i.e. location and preferences for the Celina entity and saleOffer for the shoeShop entity). Since Celina’s smartphone has GPS navigation, 3G and Wifi communication, three sources of context have been specified to determine Celina's position: GPRS, GPS and WLAN. contextSource GPRS { interfaceID: "gprs01" methodName : "getLocation" { supply : Celina.location returnValue : "WGS84"} } contextSource GPS { interfaceID : "gps01" methodName : "getLocation" { supply : Celina.location returnValue : "WGS84"} } contextSource WLAN { interfaceID : "wlan01" methodName : "getLocation" { supply : Celina.location returnValue : "WGS84"} } As indicated in the Tutorial on context modeling, the keyword interfaceID specifies the name of the interface for the context source, and the keyword methodName specifies the name of the method to be invoked to obtain the value for the property. Each method specifies the property for which the value is supplied (Celina.location in this case) and the type of the value returned (WGS84 coordinates in this case). With regard to the Celina's preferences, we will suppose that her preferences are stored in her smartphone and can be retrieved by a software agent, so we have defined a ”Smartphone Agent” source with a method ”getPreferences” as follows. . contextSource Smartphone_Agent { interfaceID : "sm01" methodName : "getPreferences" { supply : Celina.preferences returnValue : "String"} } A context source "Shop scheduler" would also be defined to express how the sale offers are obtained from the shoeShop entity. contextSource Shop_scheduler { interfaceID : "sh01" methodName : "getSaleOffer"{ supply : shoeShop.saleOffer returnValue : "String"} } Once the entities are defined, we can specify the categories to which they belong. 6 categories { User:Celina Shop:shoeShop} We have not specified a category for the smartphone entity, so MLContext will generate automatically one category for it which would be called C_smartphone. The final context model This section shows an outline of the final context model. The complete context model specification can be found in Appendix A. 7 Writing the application model The application model is specific for a concrete context-aware application and includes the following information: technical data about sensors, quality parameters, context situations (optional), quality levels (optional) and quality requirements (optional). We will create an application model named "Flash_sale.mlctq". The .mlctq extension is used by MLContext to identify an application model. Select the "Tutorial-2" folder and press the right button of the mouse to bring out the pop up window, and then select New -> File Enter the name of the file Press the button and the new file will open in the editor window. We will create an application model named "evry2mallqoc" because this is the name of the scenario in the example [Chabridon et al., 2013]. The application model is defined by using the "qualityModel" keyword. qualityModel evry2mallqoc { } The problems tab will show an error. 8 This is because the application model needs to refer to a context model. We must specify where is located the context model by adding an IMPORT sentence. We need to indicate the absolute path to the Flash_sale.mlctx file. An example of absolute path in Windows could be as follows. qualityModel evry2mallqoc { import "C:\ECLIPSE-PLUGIN\eclipse\workspace\Tutorial-2\Flash_sale.mlctx" } The path will vary depending on where is located your Eclipse workspace. If you are using Linux, this path will be something like /home/user01/eclipse/workspace/Tutorial-2/Flash_sale.mlctx In Windows (but not in Linux) it is also possible to use a relative path to the Eclipse workspace import "\Tutorial-2\Flash_sale.mlctx" If we specify a wrong path we can find two errors among others: - "resource xxx not found" An exception occurred while resolving the proxy This is because MLContext can't find the context model. The problems tab might show some other errors about unreferenced elements if we have defined references to the context model. Specify providers The context sources that we defined in the context model are attached to physical adapters or providers. Next, we will specify the providers for the three context sources defined for the Celina's location (i.e. GPRS, GPS and WLAN). A provider is defined by specifying the interface of the context source to which it is attached (e.g. gps01, wlan01). 9 provider gprs01 { name : "3G_cell_id" location : smartphone method : getLocation { units : "meters" accuracy : "500"}} This is the interfaceID that was defined for the contextSource GPRS in the context model. Therefore, the provider "3G_cell_id" is linked to that context source. This is the name of the method defined in the gprs01 interface for which we want to specify quality parameters. The definition of a provider consists of three elements: name, location and method. The name is used to give a unique id to the provider. The location indicates where the provider is located and its value can be a textual description of the location or an entity from the context model. In our scenario, the providers for the Celina's location are located in Celina’s smartphone. We can specify some quality parameters for each of the method defined in the context source interface (identified by the keyword method). In our scenario, there is only one method defined in the interface (getLocation) and we have specified an accuracy of 500 meters for the GPRS provider (this data is obtained from the manufacturers' specification). The list of quality parameters supported for MLContext can be found in Appendix B. We can specify the other providers for the GPS and WLAN sources of context as follows. provider gps01 { name : "GPS_manager" location : smartphone method : getLocation {units : "GPRS"}} provider wlan01 { name : "WIFI_manager" location : smartphone method : getLocation {units : "GPRS"}} provider wlan01 { name : "Bluetooth_manager" location : smartphone method : getLocation {units : "GPRS"}} Note that several providers can be defined for a given interface. For instance, we have defined two providers for the interface ”wlan01” of the WLAN context source in our context model. The Celina user position could therefore be obtained from two different providers (”WIFI manager” and ”Bluetooth manager”) from the WLAN context source attached to this entity. We also define the ”User profile manager” and the ”Shop manager” providers in the same way. These two providers do not have any quality parameters in this example provider sm01 { name : "User_profile_manager" location : smartphone method : getPreferences } provider sh01 { name : "Shop_manager" location : "Shop" method : getSaleOffer } 10 Specify context situations A context situation is a set of constraints on context information so that when these constraints are satisfied in the sensed environment, the situation is said to occur. This set of constraints constitutes a logic predicate. For example, the health status of a patient could be based on his/her context information about temperature, blood pressure and pulse so that the context situation ”the patient is ill” could be formed of the ”temperature>37ºC” constraint among others. We will refer to context facts as such constraints on context information (e.g. temperature > 37, pulse < 72). Therefore, a context situation is a boolean expression that is based on context facts. We can define a ”flash_sale_alert” context situation that checks if the user is near a shop that has a flash sale offer matching the user preferences. situation flash_sale_alert { #Celina.location==#shoeShop.location AND #Celina.preferences==#shoeShop.saleOffer } This context situation is formed of two context fact connected by the AND logic operator. References to context properties (i.e. properties of entities defined in the context model) are preceded by the symbol '#' (e.g. #Celina.location). The first context fact checks if the location of Celina is equal to the location of the shoe shop. The second one checks if Celina's preferences are equal to the shoe shop sale offers. MLContext has the following relational operators: ==, <,>,<=,>=, !=, as well as logic operators: AND, OR, NOT. We can also use parentheses (round brackets) in the expressions. The comparison #Celina.preferences==#shoeShop.saleOffer is an oversimplified way to check if Celina' preferences match the store sale offers. On the one hand the user Celina might have more than one preference. On the other hand, the shop can also have more than one offer. We can specify that the task of comparing preferences and sale offers will be carried out by an extern function. Therefore the context situation would be defined as follows. situation flash_sale_alert { #Celina.location==#shoeShop.location AND _flash_sale_offer_matching_user_info (#Celina.preferences, #shoeShop.saleOffer)==true } This definition makes use of an extern function "_flash_sale_offer_matching_user_info" which has two parameters: Celina preferences and the shoeShop sale offers. In MLContext, a call to a extern function is specified by using the name of the extern function preceded by an underscore "_". The context situation we have defined can be applied only to the user Celina and the shoeShop, but we are interested in check this situation for any user and any shop. In this sense we can parameterize the context situation as follows. 11 situation flash_sale_alert (u:User, s:Shop) { #u.location==#s.location AND _flash_sale_offer_matching_user_info (#u.preferences, #s.saleOffer)==true } We have added two parameters (u, s) to the context situation of type User and Shop respectively. The type of a parameter can be any of the categories defined in the context model. MLContext also allows us to define parameters using the primitive types Int, Float, String and Boolean. Now, we can use these parameters in the context facts instead of the user Celina and the shoeShop (e.g. #u.location). MLContext checks if the property location belongs to the User category (in this example). For example if we wrote #u.position, MLContext will report the following error. Note: MLContext infers the properties of the Categories from the entities belonging to them. Now, we want to compute the user location in a more precise way. As the user is moving we can compute the value of the real position based in the reported location and the speed of the user. Therefore we can introduce a "_Speed" function which computes the speed vector of the user using the position history of the user as stored on the smartphone (note that we specified the historic modifier for the user location property in the context model). We can also use an ”_AdjustedLocation” function which will compute the value of the real position, based in the reported location and the speed of the user. Taking into account these new functions, the context situation will be defined as follows. situation flash_sale_alert (u:User, s:Shop) { _AdjustedLocation(#u.location,_Speed(#u.location))==#s.location AND _flash_sale_offer_matching_user_info (#u.preferences,#s.saleOffer)==true } Next, we can improve the legibility of the specification because MLContext allows composition of context situations. 12 We can split this definition into two context situations. situation flash_sale_alert (u:User, s:Shop) { user_near_shop(#u,#s) AND _flash_sale_offer_matching_user_info (#u.preferences,#s.saleOffer)==true } situation user_near_shop(u:User, s:Shop) { _AdjustedLocation(#u.location,_Speed(#u.location))==#s.location } Specify quality requirements We can specify quality requirements for any context fact, including those that invoke a context situation. For example: situation flash_sale_alert (u:User, s:Shop) { user_near_shop(#u,#s) [freshness >= "0.8", accuracy < "10", trustworthiness >= "0.9"] AND _flash_sale_offer_matching_user_info (#u.preferences,#s.saleOffer)==true } In this example we have specified quality requirements for freshness, accuracy and trustworthiness when computing the "user_near_shop" context situation. Specify quality levels Another way of specifying quality requirements is by defining quality levels. A quality level specifies restrictions on the values that can take one or more quality parameters. Each level is identified by a unique label. We will define three quality levels in this scenario as follows. quality { QUALITY_HIGH : [freshness >= "0.8", accuracy <"10", trustworthiness >= "0.9"] QUALITY_MEDIUM : [freshness >= "0.8", accuracy <"10", trustworthiness < "0.9"] QUALITY_LOW : [freshness < "0.8", accuracy <"10", trustworthiness < "0.9"] } Now we can use these quality levels to specify quality requirements in the context situations situation flash_sale_alert (u:User, s:Shop) { user_near_shop(#u,#s) [QUALITY_HIGH] AND _flash_sale_offer_matching_user_info (#u.preferences,#s.saleOffer)==true } 13 The final application model This section shows an outline of the final application model. The complete context model specification can be found in Appendix C. 14 Generating code from the model This section assumes that you have installed and configured the MOFScript plug-ing. If not, you can install it from Eclipse: Menu Help-> Install New Software... and press de Add.. button to add the MOFScript Site. When the Add site window appears, you can enter the following url in "Location": http://www.modelum.es/MLContext/mofscript You can adjust your MOFScript preferences from Menu Window->Preferences->MOFScript preferences. The output directory for the generated code if you check this option, Eclipse will generate a project with links to the generated code First, you need to copy the file MLContext.m2t in your project (it contains the MLContext API). Next you must copy the file containing the model transformation (cosmos.m2t). Both files (MLContext.m2t and cosmos.m2t) can http://www.modelum.es/MLContext/documentation.htm. be downloaded from a zip at Note: MOFScript creates the generated files in its default folder. You can specify the folder to store the generated code. To do so, select the cosmos.m2t file and right-click the mouse. Then select Properties. To execute the transformation select the file cosmos.m2t and click the right mouse button to open the pop-up menu: Select MOFScript -> Execute. A new window opens to select the file containing the .mlctq model. Select the file Flash_sale.mlctq from your project. 15 Press OK. Another window opens to select the file containing the .mlctx model. Select the file Flash_sale.mlctx from your project. Press OK. 16 The code generation starts and new files are generated in the Root Generation Dir specified in the MOFScript plug-in preferences. If you have selected the "Generate Eclipse Project with links" in the MOFScript plug-in preferences a new project will be added in the explorer window with links to the new generated files. If not you will find these files in the output directory. links to generated files The file flash_sale_report.txt contains the generation reports for the context model. The file flash_sale_alert.cosmos and the user_near_shop.cosmos files contain the generated COSMOS DSL specification for the flash_sale_alert and user_near shop context situations respectively. This transformation generates a COSMOS dsl file for each of the context situations defined in the model. However only the flash_sale_alert.cosmos is necessary because it already includes the user_near_shop specification (the context situation flash_sale_alert include a call to the other context situation). 17 Appendix A – Context model specification contextModel flash_sale { //-----entities----entity Celina context { environment {"location" source historic} personal {"preferences" source "carrying" : smartphone}} entity smartphone context {} entity shoeShop context { environment{"location" : "37.607602, -0.975380" units : "WGS84"} computational{"saleOffer" source}} //-----context sources----contextSource GPRS { interfaceID : "gprs01" methodName : "getLocation" { supply : Celina.location returnValue : "WGS84"} } contextSource GPS { interfaceID : "gps01" methodName : "getLocation" { supply : Celina.location returnValue : "WGS84"} } contextSource WLAN { interfaceID : "wlan01" methodName : "getLocation" { supply : Celina.location returnValue : "WGS84"} } contextSource Smartphone_Agent { interfaceID : "sm01" methodName : "getPreferences" { supply : Celina.preferences returnValue : "String"} } contextSource Shop_scheduler { interfaceID : "sh01" methodName : "getSaleOffer"{ supply : shoeShop.saleOffer returnValue : "String"} } //-----categories----categories { User:Celina Shop:shoeShop} } 18 Appendix B –Quality parameters • units. A unit is "a quantity chosen as a standard in terms of which other quantities may be expressed". They are used to express the value of data information. On the one hand, sources of context may provide a value using different units from those required by an application. On the other hand, the application could not know the units in which a value is expressed. A context-aware framework should be able of converting the value supplied by the source to the units required by the application. • precision. Precision is "the degree to which repeated measurements under unchanged conditions show the same results". Precision it is also called repeatability or reproducibility. An ideal sensor would output the same value every time the value is measured, but real sensors output a range of values relative to the actual correct value. For example, for a weight of exactly 1.110 gr. we can use a weight sensor with a precision of 0.1 gr. and the output values for successive measures will vary considerably (e.g. 1.121 gr., 1.100 gr., 1.107 gr., etc.). All those measures differ from the second decimal position because the precision of the sensor is 0.1 gr. • accuracy. The accuracy of a measurement is "the degree of closeness of a quantity to its actual (true) value". Therefore the accuracy of a sensor is the maximum difference between the true value and the supplied value at the output of the sensor. Actually, despite its name, this parameter expresses inaccuracy, and it can be expressed as a percentage or in absolute terms. The difference between precision and accuracy is correctness. For example, a precise measurement of 1.128 gr. (with a precision of 0.001 grams) has this value every time it is measured but it could be wrong if the true value is 1.120 gr. • range. The range of the sensor is "the maximum and minimum values of applied parameter that can be measured". For example, the output of a weight sensor will be wrong when we apply a weight of 1020 grams if it has a range from 0 to 1000 grams, because it exceeds the maximum weight. A context-aware application should take this into account. The range of a sensor can be expressed by means of its maximum and minimum values. • freshness. Freshness refers to "how current the provided information is at the time of delivery". A source of context should indicate the time of the data acquisition. For example, a navigation system needs updated information about the user's location). While some information remains valid over time, other may become discredited or obsolete. • trustworthiness. Trustworthiness is "the extent to which information is regarded as true and credible". Sometimes, it is seen as expected accuracy, but there are some differences. While accuracy refers to the verifiable precision of a value supplied by a sensor, believability refers to trusting the value of the data without checking it. 19 Appendix C – Application model specification qualityModel evry2mallqoc { import "\Tutorial-2\Flash_sale.mlctx" //linux users must use absolute path provider gprs01 { name : "3G_cell_id" location : smartphone method : getLocation { units : "meters" accuracy : "500"}} provider gps01 { name : "GPS_manager" location : smartphone method : getLocation {units : "GPRS"}} provider wlan01 { name : "WIFI_manager" location : smartphone method : getLocation {units : "GPRS"}} provider wlan01 { name : "Bluetooth_manager" location : smartphone method : getLocation {units : "GPRS"}} provider sm01 { name : "User_profile_manager" location : smartphone method : getPreferences } provider sh01 { name : "Shop_manager" location : "Shop" method : getSaleOffer } //context situations situation flash_sale_alert (u:User, s:Shop) { user_near_shop(#u,#s) [QUALITY_HIGH] AND _flash_sale_offer_matching_user_info (#u.preferences,#s.saleOffer)==true } situation user_near_shop(u:User, s:Shop) { _AdjustedLocation(#u.location,_Speed(#u.location))==#s.location } //quality levels section quality { QUALITY_HIGH : [freshness >= "0.8", accuracy <"10", trustworthiness >= "0.9"] QUALITY_MEDIUM : [freshness >= "0.8", accuracy <"10", trustworthiness < "0.9"] QUALITY_LOW : [freshness < "0.8", accuracy <"10", trustworthiness < "0.9"] } } 20 References S. Chabridon, D. Conan, Z. Abid, C. Taconet, Building ubiquitous qoc-aware applications through model-driven software engineering, Science of Computer Programming 78 (10) (2013) 1912 – 1929. 21