WET WADE Project

Authors

  • Rareș Mircea
  • Petru Marțincu
  • Cristian Hasna

Abstract

WET - Web of Things Platform is a Web tool that allows individuals to create groups of devices, interact with them, manage permissions to other users or visitors, which are represented by temporary users which are invited to join a group.

We wish to develop a platform that allows ease of use, friendly & responsive UI and easy management and iteraction smart devices.

Architecture

The architecture of our platform is split into two main components: a front-end which is represented by a client built over Angular 11 with Material Design including components of Angular Material and a back-end represented by two smaller components, one being the Python Flask API.

Diagrams

The following diagrams illustrates the working flow of our application

statechart diagrams

Back end

At the core of our data modeling we identify 4 core entities: Users, Devices, Permissions and Groups

Users are represented by the people that will interract with our application, holding key information regarding identifiers: id, email, name, password and mobile phone.

We used Groups as a way to represent the similarity of User's access rights. Groups can consist of one or more Users and hold the permissions that will take effect upon different actions on our devices.

Devices are nothing but simple electonics that have the ability to connect to the local network and communicate with our application. Devices can be discovered and attached to a certain group.

In order to represent the permissons that take place between users and devices we modeled the Permissions entity that holds information related to basic READ, WRITE and MANAGE roles as well as the device we have created this permissions. Groups hold these permissions we created, and can be more than 1.

backend arhitecture

In order to manage the described entities, we created controllers for each module: devices, authentication and groups. Using these controllers we obtained full access in creating a suitable REST API to fulfill our needs.

classes

Managing the devices is done in multiple ways: discovering the available devices on a network, which are saved at group level under 'was discovered', point at which we first assign an id to them. We also have the possibility to dispaly the paired devices to a group, or even send commands to a certain device.

Group controllers took up more functionality than the other two controllers, having multiple jobs assigned: adding permissions and members to a group, creating a new group, retriving the groups associated with the current authenticated user, getting a short summary or full data about a group.

For the authentication component, we have implemented the login functionality (done with username and password). This will restrict unauthorized users from accesing sensitive data and prevents unwanted actions taking place. In case of login, we are making use of a token to authenticate further actions on the application, without the need of constantly entering credentials. For the last part we also implemented a mechanism for registering, during which the Users entity will be populated with information like a encrypted password and username.

classes

Knowledge Model

The following figure represents our knowledge model:

classes

User entity:

Property Type / Range Description
rdf:type User User type definition
id UUID User's name
name string The name of the user
username string User's credential need to interact with the application
password string Password which has been hashed on user account creation
phone string User's phone number

Group entity:

Property Type / Range Description
rdf:type Group Group definition
id UUID Unique identifier for group
name string Group's name
isOwnedBy User User entity that owns the group
hasMember List<User> User entities that are part of the group. Owner is part of this too.
hasDiscovered List<Device> Device entities that were found during discovery and are being linked with this group due to an increased chance of adding them in the future
consistsOf List<Device> Device entities actually linked with the group, and the users in that group will be able to see them, and interact with them
hasPermission List<Permission> Permission entities that store the permssion for a given member and device

Device entity:

Property Type / Range Description
rdf:type Device Device definition
id UUID Unique identifier for device
name string Producer name for this device
nickname string Nickname given by the user

This is how the device is being constructed from the WoT Thing definition represented by saref:Device and device:Device. The definition is added on demand to the actual device with it's corresponding properties and actions, and on our DB we store only device:Device entity, and the parent entity(e.g. device: bulb)

It is a compromise solution, which allowed us to successfully expose the saref:Device properties and actions to the client side. Actions and properties will be used to interact with the device itself through our API, using the link provided for each action and properties.

Example for action API call: /groups/<group_id>/devices/<device_id>/<command>

classes

In the following picture, we have chosen device from a group which is included in GET /groups/<group_id> to represent the combined device model more clearly.

classes

Permission entity:

Property Type / Range Description
rdf:type Permission Permission definition
id UUID Unique identifier for permission
memberId string This is represented by the Group's member id which this permission targets
groupId string This is represented by the Group's id which this permission targets
read boolean Permission to Read device properties
write boolean Permission to Write (interact) with device actions
manage boolean Permission to Manage (Super User)

SPARQL

Interaction with SPARQL was made using Fuseki WebApp, and it helped visualising the query results and how to map them against the model, and with SPARQL Wrapper in Python.

The following query is used during the construction of the GET /groups/:group_id request. The way we designed the group is that we initially create the group itself, then allow the user to add devices and/or set permissions for them. This being said, initially we would not have any values that populate the consistsOf and hasPermission relations and teh query would fail. Given this, without the OPTIONAL operator the query will fail on the initial state of the group.

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX groups: <http://www.semanticweb.org/ontologies/groups#>
PREFIX users: <http://www.semanticweb.org/ontologies/users#>
PREFIX devices: <http://www.semanticweb.org/ontologies/devices#>
PREFIX permissions: <http://www.semanticweb.org/ontologies/permissions#>
SELECT *
WHERE {
?group rdf:type groups:Group ;
   groups:id "{group_id}" .
?group groups:name ?name .
?group groups:id ?id .
?group groups:isOwnedBy ?owner .
?owner users:id ?owner_id .
?owner users:name ?owner_name .
?group groups:hasMember ?member .
?member users:id ?member_id .
?member users:name ?member_name .
OPTIONAL {
   ?group groups:consistsOf ?device
   ?device devices:id ?device_id .
   ?device devices:name ?device_name .
   ?device devices:nickname ?device_nickname .
   ?device a ?device_type .
}
OPTIONAL {
   ?group groups:hasPermission ?permissions .
   ?permissions permissions:deviceId ?permission_device_id .
   ?permissions permissions:memberId ?permission_member_id .
   ?permissions permissions:manage ?permission_can_manage .
   ?permissions permissions:read ?permission_can_read .
   ?permissions permissions:write ?permission_can_write .
   }
}

Another interesting query, or command to be more exact, is the one for updating permissions. Due to the nature of the SPARQL, there are no UPDATE statements per se, but combined DELETE - INSERT statements, this is due to the necessity of deleting the nodes and recreating them. Here we used the FILTER operator to select only the permission referring to that member and device.


DELETE {{
  ?permissions permissions:memberId ?permissions_member_id .
  ?permissions permissions:deviceId ?permissions_device_id .
  ?permissions permissions:manage ?permission_can_manage .
  ?permissions permissions:read ?permission_can_read .
  ?permissions permissions:write ?permission_can_write .
}}
INSERT {{
  ?permissions permissions:memberId "{permission["memberId"]}" .
  ?permissions permissions:deviceId "{permission["deviceId"]}" .
  ?permissions permissions:manage "{int(permission["manage"])}" .
  ?permissions permissions:read "{int(permission["read"])}" .
  ?permissions permissions:write "{int(permission["write"])}" .
}}
WHERE {{
  ?group rdf:type groups:Group ;
    groups:id "{group_id}" .
  ?group groups:hasPermission ?permissions .
  ?permissions permissions:memberId ?permissions_member_id .
  ?permissions permissions:deviceId ?permissions_device_id .
  ?permissions permissions:manage ?permission_can_manage .
  ?permissions permissions:read ?permission_can_read .
  ?permissions permissions:write ?permission_can_write .
  FILTER (?permissions_member_id = "{permission["memberId"]}"
    && ?permissions_device_id = "{permission["deviceId"]}") }}

Back End

Back-End Motivation

We prefered using Python due to it's increased flexibility regarding types, allowing us to focus on the relations we built din the database and how to extract, parse and expose them to the client. Combining the following components, where where able to create a streamlined flow from the initial request, to the final response itself.

Flask Application was hosted on a Heroku instance running Python, and initially posed some issues because we were not able to use any known Linked Data databases, and storing data directly into files was out of the question. After a bit of research, we found out that it is possible to host Fuseki, which is the WebApp running Jena, on the cloud.

Heroku being our selected Cloud Services Provider we raised another instance running Java, and with some small changes we managed to establish a link between API and LinkedData storage. This greatly increased our ability to interact with the storage, due to the fact that it was shared accross development and production environments.

Flask

It is a framework which extends the python application to a capable Web API. With the built-in modules, Flask is very potent ranging from the ability of declaring controllers and structure them using Blueprint, to even a module consisting of handling. With this being said, it allowed us to quickly and easily construct endpoints.

SPARQLWrapper

Wrapper around SPARQL Service, which helps in creating the URI and coverting the result into a manageable format. Being a Python module it was integrated successfully in our application and was integrated as an abstractized class which called the two endopoints from Jena - /update and /query.

Jena & Fuseki

Apache Jena is an Open-Source Java Framework for building semantic web and Linked Data applicaitons. It suited our needs for storing Linked Data in a database, and combined with Fuseki, which is a WebApp that runs Jena, it allowed us to directly view and query the data, not limiting us to SPARQL queries that would have been difficult to create.

user interface routing
Example of a SPARQL Query directly from Fuseki WebApp and the output

user interface routing
Exemple of triples being stored, with the possibilty of modifying the data.

User Interface / User Experience

UI Motivation

This application is mainly focused on mobile devices, therefore we need a simple layout, that the user can easily interact with in a tactile manner.

The screens hierarchy has been structured with the focus on the group entity, as that's where the user will spend most of its time. The following figure illustrates the screens hierarchy.

user interface routing

In the next sections we will discuss each screen with respect to its functionality, layout and UI/UX considerations.

UI Screens

Splash Screen

Although the splash screen is not really visible, it is present, and it's purpuse it's to decide the further direction that the user should take in our application.

It primarily tries to redirect to the user groups screen, and if that fails due to the user not being authenticated, it will redirect the user to the authentication module.

Group Joining Screen

In the context of WET application, users can adhere to other groups by accessing a special joining address, that needs to be shared by the creator of the group.

This screen has no other purpose than presenting the user with the group that he's about to join, and checking if they're logged in or not, in which case an input asking for the user's name will be shown, so the user can join the group as a temporary member.

join group

After confirming the group join, the user will be (authenticated if they're a temporary group member and) redirected to the main screen of the application, which is the group list, that we will discuss later.

Login Screen

In the case that the user is not authenticated, and he is not accessing a group join link, the login screen is the first interaction with the application

The purpose of this screen is clear, we need to authenticate already registered users via username and password.

login

The user is presented with a minimal form, with 2 fields: username and password. There is also a button to redirect to the registration screen, in case the user is not already registered.

These fields have a validation that ensures the fields are not empty, and disables the submit button otherwise.

login

Register Screen

The registration screen is very similar with the login screen, both in user experience and purpose. If the user has no registered account, they can chose to create an account, via the registration form.

login

This screen has a link back to the login screen, in case the user got here by mistake, and they already have an account.

Both the registration and the login screen will redirect the user to the main screen after the authentication is successful.

Main Screen (Groups list screen)

The main screen of the application presents the user with all the groups that they are a member of. The groups are presented in a mobile-friendly manner, using cards, and large control buttons.

login

Each group card may have two options: group settings, and group devices.

  • Group settings button will redirect the user to the group settings, which we will discuss later. This option is available only for the creator of the group.
  • Group devices button will redirect the user to the devices screen, which we will also discuss later. This option is available for each member of the group.

It is worth noting that there is a button that allows the user to create a new group. This button will show a modal that requires the user to input the group name, and will create a new group with that name. This option is available just for the registered accounts, so temporary group members will not be able to create groups

login

Group Settings

The group owner has access to a settings screen, where they will be presented with a few posible actions.

login

First, the owner has the option to invite other members to their group by sharing a group join link, and the process is described in this section.

Then the user has the ability to delete their group, which will delete any temporary users as well as its associated devices.

Furthermore, the owner of the group can see a list of all the group members, including himself, and they can also remove any member of the group.

login

Group Devices

Each group member can see the list of devices associated with the group. These devices are presented using cards along with minimal information including a nickname, device name, device type.

The device cards contain a descriptive icon based on the device type.

login

It is worth noting that the group owner has the option to add new devices to the group, by discovering devices.

Discover Devices Screen

The group owner has access to add new devices to the group, by discovering devices.

These discovered devices are displayed in a list, with information about the device's name, type and an easy to access button that facilitates the addition of the device to the group.

login

The group owner is then presented with a modal that requires a nickname for the selected device, after which the device will be associated with the group

login

Device Control Screen

The device control screen is probably the most important part of the application, as it facilitates the control of the device, which the entire application is based upon.

According to each member's access rights, the user can see the information about the device, can modify properties like temperature, and can also manage the access rights of other users.

login

No group member can modify the access rights of the group owner.

Technical Considerations

The above described UI was implemented using the Angular 11 framework, which is based on JavaScript with support for TypeScript.

A structure of the project modules is illustrated in the following figure:

angular modules