Skip to content

How to create a new service

Olivier Mével edited this page May 10, 2021 · 4 revisions

This tutorial is based on the nabairqualityd service to show you how to create a service that will display visual messages on the rabbit as well as play a sound when triggered by a voice command. I'll also show you how to configure the service on the admin page.

To start, it's a good idea to read CONTRIBUTING, it gives some information if you want to publish your developpement.

Create the django app

source venv/bin/activate

python manage.py startapp YourNewServiced

A few magic things to perform

Copy urls.py and the template directory from nabairqualityd (you need to modify the service name inside the directory).

  • urls.py is used to map the "settings" page to ....( Paul ?)
  • the template directory contains the settings.html file that will implement the interface to modify the configuration data

You also need :

  • to put NABAZTAG_SERVICE_PRIORITY = <int> ( is an integer that will determine the rank of your service) in init.py a
  • add YourNewServiced in the INSTALLED_APPS section of nabweb/settings.py ()

You're now ready to develop your own service.

New service development

Data

All the persistent data (whether they are configurable by the user or you just use them in your service) needs to be in models.py

YourNewServiced.py

YourNewServiced.py is where all the action takes place. Lets explore this VIP script:

First you have to choose a base class for your service. Currently there are :

  • NabRecurrentService : base class for recurrent services that can be triggered from the websit (or with the voice recognition service)
  • NabInfoService : base class for services that display info (animations) updated on a regular basis and which can be triggered from the website.
  • NabInfoCachedService : base class for an info service which additionally caches the remote info locally, to minimize delay for on-demand performances (voice, website).
  • NabRandomService : Common class for Tai Chi and Surprise.

For nabairqualityd we choose NabInfoCachedService as the service needs to update information gathered from the internet and we don't want to fetch data for every request of the service.

There are 3 or 4 functions to write (the others are common among every services).

next_info_update(self, config) This method is optional, by default information is updated every hour but if you want to change it you need to use this. config is the third element returned by get_config

fetch_info_data(self, config) This method is used to get data from the internet, it returns info_data (in our example : it returns the air quality index)

get_animation(self, info_data)

This methods returns the animation that will be displayed on Nabaztag. Return None if you don't want anything to be shown. info_data is the result of the fetch_info_data call

perform_additional(self, expiration, type, info_data, config)

This method plays an audio message

config = third element of the get_config triplet type = second element of the get_config triplet info_data = fetch_info_data return

This method can end with await self.writer.drain()

sounds directory

Put here all the sounds you need. You need to put them in the correct language directory (fr_FR for example) if the sound is spoken in a specific language

nlu

This where you tell the voice recognition engine how your service will be activated. For example, in nabairqualityd, the following sentence spoken to the Nabaztag will trigger the service : "give me an air quality bulletin"

You can check the following page for more details.

settings.html (in template)

This is the HTML interface for your service. You need to adapt it to your data model and use the same variable name as in the models.py file.

views.py

This where you process the configuration data in the "post" method (you don't need to change anything in the "put" method).

Migrations, update and reboot

Once you've done everything, you need to perform a few actions to tell Django to update the database and to install the different scripts.

(YourNewService.service : you can modify the nabairquailityd.service, it tells systemctl how to launch your service at boot)

You can also clean up your code with black : ./venv/bin/black -l 79 -t py37 /*.py or use ./venv/bin/pre-commit (as mentionned in CONTRIBUTING.md)

python manage.py makemigrations

python manage.py migrate

sudo service nabweb restart

sudo cp <YourNewService.service> /lib/systemd/system/

sudo systemctl enable YourNewService.service

sudo systemctl start YourNewService

sudo reboot

How to test your service

To test your code and see all the potential errors, it's easier to launch it first with the command line (you need to stop the service before) :

sudo systemctl stop YourNewServiced

sudo venv/bin/python -m YourNewServiced.YourNewServiced

You can also add Unit tests

Internationalization

Django provides an easy way to translate the texts of your setting.html.

First make sure you used the {% trans "Your texte here"} directive in your html file then :

  1. Copy the "locale" directory from elsewhere
  2. Cd to your service directory
  3. django-admin makemessages : this will take every text in your html config and put in in a .po file (in locale directory)
  4. add the translation of your texts in the .po files
  5. one you're done : django-admin compilemessages and sudo systemctl restart nabweb (to see the changes in the web interface)