Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

The code for all the services can be found at https://bitbucket.org/socialroboticshub/processing/src/master/ . Creating a new service can be done as follows, and then included in the repository by opening a Pull Request:

  1. create a new folder in https://bitbucket.org/socialroboticshub/processing/src/master/ with the name of the service. my_service will be used as the example folder and service name in this case

  2. copy the certificate file https://bitbucket.org/socialroboticshub/docker/src/master/cbsr/beamforming/cert.pem from any of the other services' folders into the my_servicefolder

  3. create a my_service_factory.py file in the my_service folder

from cbsr.factory import CBSRfactory
from my_service import MyService


class MyServiceFactory(CBSRfactory):
    def __init__(self):
        """ MyServiceFactory constructor
            inherit from the CBSRfactory constructor to create the new service as a service
        """
        super(MyServiceFactory, self).__init__()

    def get_connection_channel(self):
        """ initialise the name of the service Redis channel
        """
        return 'my_service'

    def create_service(self, connect, identifier, disconnect):
        return MyService(connect, identifier, disconnect)


if __name__ == '__main__':
    my_factory = MyServiceFactory()
    my_factory.run()

4. create a my_service.py file in the my_service folder

""" This file shows an example of a mock service that uses the text_transcript channel result
    from the Dialogflow speech-to-text and publishes it into the new my_service channel.
    The file can be extended to as many services as necessary
"""

from cbsr.service import CBSRservice


class MyService(CBSRservice):
    def __init__(self, connect, identifier, disconnect):
        super(MyService, self).__init__(connect, identifier, disconnect)

    def get_device_types(self):
        """ :return list of devices the service uses
            This method returns a list of all the devices my_service uses; in this case, only the microphone
        """
        return ['mic']

    def get_channel_action_mapping(self):
        """ :return key-value dictionary pairing, with listened channel as key and linked method as value;
                    multiple channels can be listened to, linked to a method when separated by a comma in the output dictionary
            Use an already-existing channel and links it to a method to be called when there is a message in the channel
            The channel should correspond to one of the topics in abstract_connector.py; 
            in this case, my_service uses the text_transcript channel and links it to the method self.execute
        """
        return {self.get_full_channel('text_transcript'): self.execute}

    def execute(self, message):
        """ :param message: the message published in the channel the method was linked to
            This method decodes the data received in the channel it was linked to and further publishes
            a message in the new service channel
            Extra functionalities can be added to the method
        """
        sentence = message['data'].decode()
        self.publish('my_service', sentence)

5. update the https://bitbucket.org/socialroboticshub/processing/src/master/deploy_to_docker.sh file in the root folder with the new service files

...
echo Deploying my_service...
cd ../my_service
cp -f {cert.pem,  *.py} ../../docker/cbsr/my_service    # extra files can be copied if used
...

6. deploy the new service to the https://bitbucket.org/socialroboticshub/docker/src/master/ folder by running the deploy_to_docker.sh file

7. update the https://bitbucket.org/socialroboticshub/docker/src/master/docker-compose.yml file in the docker folder with the new service

# ------------------------------------------------------------
# My service
# ------------------------------------------------------------
my_service:
  image: python3
  build:
    context: .
    dockerfile: Dockerfile.python3
  hostname: my_service
  user: "${NEW_UID}:${NEW_GID}"
  env_file:
    - ./.env

  working_dir: /my_service
  command: python3 my_service_factory.py
  volumes:
    - ./cbsr/mock:/my_service:rw${MOUNT_OPTIONS}

  tty: true
  stdin_open: false

  networks:
    app_net:
      ipv4_address: 172.16.238.x   # address has to differ from those of the already existing services' 

  depends_on:
    - redis
    - dialogflow
  # - any other services my_service depends on

8. add the name of the new service my_service into the topics list in the constructor of the Abstract Connector abstract_connector.py in the https://bitbucket.org/socialroboticshub/connectors/src/master/python/social_interaction_cloud/ folder

topics = [..., 'my_service']

9. add the service my_service to the corresponding list of devices listeners in enable_service in abstract_connector.py, if the services uses either the camera or the microphone

###########################
# Management              #
###########################

def enable_service(self, name: str) -> None:
    ...
    elif ... and name == 'my_service':
        for mic in self.devices[self.device_types['mic']]:
            pipe.publish(name, mic)
    ...

9. add the new channel my_service into the listened to channels in __listen in abstract_connector.py

...
elif channel = 'my_service':
    self.on_my_service(message=data.decode('utf-8'))
...

10. create the corresponding event handler method on_my_service in abstract_connector.py

###########################
# Event handlers          #
###########################
...
def on_my_service(self, message: str) -> None:
    pass
...

11. create the corresponding inherited event handler method on_my_service in basic_connector.py

###########################
# Event handlers          #
###########################
...
def on_my_service(self, message: str) -> None:
    """ :param message: the message published on the my_service channel
        This method notifies the listeners that a new message has been posted on the my_service channel;
        This method can be further inherited and overridden
    """
    self.__notify_listeners('onMyService', message)
...

12. use the new service by creating a new file my_service_example.pyand running it

from social_interaction_cloud.action import ActionRunner
from social_interaction_cloud.basic_connector import BasicSICConnector

class MyConnector(BasicSICConnector):
    def __init__(self, server_ip: str):
        """ :param server_ip:
            This method inherits the BasicSICConnector and enables the new my_service service;
            my_service needs to be manually enabled in this way
        """
        super(MyConnector, self).__init__(server_ip)
        self.enable_service('my_service')

    def on_my_service(self, message: str) -> None:
        """ :param message: message published in the my_service channel
            This method overrides the event function on_my_service inherited from the BasicSICConnector
        """
        print(message)
        self.stop()

  • No labels