Browse Source

Merge pull request #20 from kalliope-project/dev

Dev
Nicolas Marcq 8 years ago
parent
commit
94e397f7f2

+ 3 - 3
Docs/neuron_list.md

@@ -6,13 +6,13 @@ A neuron is a module that will perform some actions attached to an order. You ca
 |----------------------------------------------------|-----------------------------------------------------------------------------------------|-------------------|
 | [ansible_task](../neurons/ansible_task/)           | Run an ansible playbook                                                                 | ansible_task      |
 | [gmail_checker](../neurons/gmail_checker/)         | Get the number of unread email and their subjects from a gmail account                  | gmail_checker     |
-| [kill_switch](../neurons/kill_switch/)             | Stop Kalliope process                                                                     | kill_switch       |
+| [kill_switch](../neurons/kill_switch/)             | Stop Kalliope process                                                                   | kill_switch       |
 | [neurotransmitter](../neurons/neurotransmitter/)   | Link synapse together                                                                   | neurotransmitter  |
 | [push_message](../neurons/push_message/)           | Send a push message to a remote device like Android/iOS/Windows Phone or Chrome browser | push_message      |
-| [say](../neurons/say/)                             | Make Kalliope talk by using TTS                                                           | say               |
+| [say](../neurons/say/)                             | Make Kalliope talk by using TTS                                                         | say               |
 | [script](../neurons/script/)                       | Run an executable script                                                                | script            |
 | [shell](../neurons/command/)                       | Run a shell command                                                                     | shell             |
-| [sleep](../neurons/sleep/)                         | Make Kalliope sleep for a while before continuing                                         | sleep             |
+| [sleep](../neurons/sleep/)                         | Make Kalliope sleep for a while before continuing                                       | sleep             |
 | [systemdate](../neurons/systemdate/)               | Give the local system date and time                                                     | systemdate        |
 | [tasker_autoremote](../neurons/tasker_autoremote/) | Send a message to Android tasker app                                                    | tasker_autoremote |
 | [twitter](../neurons/twitter/)                     | Send a Twit from kalliope                                                               | twitter           |

+ 1 - 1
brains/script.yml

@@ -2,7 +2,7 @@
   - name: "run-simple-script"
     neurons:
       - script:
-          path: "/home/nico/test.sh"
+          path: "/var/tmp/coucou.sh"
       - say:
           message: "Script lancé, monsieur"
     signals:

+ 39 - 0
neurons/gmail_checker/README.md

@@ -0,0 +1,39 @@
+# gmail_checker
+
+## Synopsis
+
+This neuron access to Gmail and gives the number of unread mails and their titles.
+
+## Options
+
+| parameter | required | default | choices | comment    |
+|-----------|----------|---------|---------|------------|
+| username  | YES      |         |         | User info. |
+| password  | YES      |         |         | User info. |
+
+## Return Values
+
+| Name     | Description                                  | Type | sample                                                       |
+|----------|----------------------------------------------|------|--------------------------------------------------------------|
+| unread   | Number of unread messages                    | int  | 5                                                            |
+| subjects | A List with all the unread messages subjects | list | ['Kalliope commit', 'Beer tonight?', 'cats have superpower'] |
+
+## Synapses example
+
+Simple example : 
+
+```
+  - name: "check-email"
+    neurons:
+      - gmail_checker:
+          username: "me@gmail.com"
+          password: "my_password"
+          say_template: 
+            -  "You have {{ unread }} new emails"
+    signals:
+      - order: "Do I have emails"
+```
+
+
+## Notes
+

+ 1 - 1
neurons/gmail_checker/__init__.py

@@ -1 +1 @@
-from gmail_checker import Gmail_checker
+from gmail_checker import Gmail_checker

+ 39 - 29
neurons/gmail_checker/gmail_checker.py

@@ -13,45 +13,42 @@ class Gmail_checker(NeuronModule):
     def __init__(self, **kwargs):
         super(Gmail_checker, self).__init__(**kwargs)
 
+        self.username = kwargs.get('username', None)
+        self.password = kwargs.get('password', None)
+
         # check if parameters have been provided
-        username = kwargs.get('username', None)
-        password = kwargs.get('password', None)
+        if self._is_parameters_ok():
 
-        if username is None:
-            raise MissingParameterException("Username parameter required")
+            # prepare a returned dict
+            returned_dict = dict()
 
-        if password is None:
-            raise MissingParameterException("Password parameter required")
+            g = Gmail()
+            g.login(self.username, self.password)
 
-        # prepare a returned dict
-        returned_dict = dict()
+            # check if login succeed
+            logging.debug("Gmail loggin ok: %s" % g.logged_in)  # Should be True, AuthenticationError if login fails
 
-        g = Gmail()
-        g.login(username, password)
+            # get unread mail
+            unread = g.inbox().mail(unread=True)
 
-        # check if login succeed
-        logging.debug("Gmail loggin ok: %s" % g.logged_in)  # Should be True, AuthenticationError if login fails
+            returned_dict["unread"] = len(unread)
 
-        # get unread mail
-        unread = g.inbox().mail(unread=True)
+            if len(unread) > 0:
+                # add a list of subject
+                subject_list = list()
+                for email in unread:
+                    email.fetch()
+                    encoded_subject = email.subject
+                    subject = self._parse_subject(encoded_subject)
+                    subject_list.append(subject)
 
-        returned_dict["unread"] = len(unread)
+                returned_dict["subjects"] = subject_list
 
-        if len(unread) > 0:
-            # add a list of subject
-            subject_list = list()
-            for email in unread:
-                email.fetch()
-                encoded_subject = email.subject
-                subject = self._parse_subject(encoded_subject)
-                subject_list.append(subject)
+            logger.debug("gmail neuron returned dict: %s" % str(returned_dict))
 
-            returned_dict["subjects"] = subject_list
-
-        logger.debug("gmail neuron returned dict: %s" % str(returned_dict))
-        # logout of gmail
-        g.logout()
-        self.say(returned_dict)
+            # logout of gmail
+            g.logout()
+            self.say(returned_dict)
 
     def _parse_subject(self, encoded_subject):
         dh = decode_header(encoded_subject)
@@ -70,3 +67,16 @@ class Gmail_checker(NeuronModule):
                 return unicode(header, 'ISO-8859-1')
             except UnicodeDecodeError:
                 return unicode(header, 'UTF-8')
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.username is None:
+            raise MissingParameterException("Username parameter required")
+
+        if self.password is None:
+            raise MissingParameterException("Password parameter required")
+
+        return True

+ 29 - 0
neurons/kill_switch/README.md

@@ -0,0 +1,29 @@
+# kill_switch
+
+## Synopsis
+
+This neuron exits the Kalliope process.
+
+## Options
+
+No parameters
+
+## Return Values
+
+No returned values
+
+## Synapses example
+
+Simple example : 
+
+```
+  - name: "stop-kalliope"
+    neurons:
+      - kill_switch
+    signals:
+      - order: "goodbye"
+```
+
+
+## Notes
+

+ 0 - 1
neurons/kill_switch/kill_switch.py

@@ -4,7 +4,6 @@ from core.NeuronModule import NeuronModule
 
 
 class Kill_switch(NeuronModule):
-
     def __init__(self, **kwargs):
         super(Kill_switch, self).__init__(**kwargs)
         sys.exit()

+ 112 - 104
neurons/openweathermap/Openweathermap.py

@@ -8,110 +8,118 @@ class Openweathermap(NeuronModule):
         # get message to spell out loud
         super(Openweathermap, self).__init__(**kwargs)
 
-        api_key = kwargs.get('api_key', None)
-        location = kwargs.get('location', None)
-        lang = kwargs.get('lang', 'en')
-        temp_unit = kwargs.get('temp_unit', 'celsius')
-        country = kwargs.get('country', None)
-
-        if api_key is None:
+        self.api_key = kwargs.get('api_key', None)
+        self.location = kwargs.get('location', None)
+        self.lang = kwargs.get('lang', 'en')
+        self.temp_unit = kwargs.get('temp_unit', 'celsius')
+        self.country = kwargs.get('country', None)
+
+        # check if parameters have been provided
+        if self._is_parameters_ok():
+            extended_location = self.location
+            if self.country is not None:
+                extended_location = self.location + "," + self.country
+
+
+            owm = pyowm.OWM(API_key=self.api_key, language=self.lang)
+
+            # Tomorrow
+            forecast = owm.daily_forecast(extended_location)
+            tomorrow = pyowm.timeutils.tomorrow()
+            weather_tomorrow = forecast.get_weather_at(tomorrow)
+            weather_tomorrow_status = weather_tomorrow.get_detailed_status()
+            sunset_time_tomorrow = weather_tomorrow.get_sunset_time('iso')
+            sunrise_time_tomorrow = weather_tomorrow.get_sunrise_time('iso')
+
+            temp_tomorrow = weather_tomorrow.get_temperature(unit=self.temp_unit)
+            temp_tomorrow_temp = temp_tomorrow['day']
+            temp_tomorrow_temp_max = temp_tomorrow['max']
+            temp_tomorrow_temp_min = temp_tomorrow['min']
+
+            pressure_tomorrow = weather_tomorrow.get_pressure()
+            pressure_tomorrow_press = pressure_tomorrow['press']
+            pressure_tomorrow_sea_level = pressure_tomorrow['sea_level']
+
+            humidity_tomorrow = weather_tomorrow.get_humidity()
+
+            wind_tomorrow = weather_tomorrow.get_wind()
+            # wind_tomorrow_deg = wind_tomorrow['deg']
+            wind_tomorrow_speed = wind_tomorrow['speed']
+
+            snow_tomorrow = weather_tomorrow.get_snow()
+            rain_tomorrow = weather_tomorrow.get_rain()
+            clouds_coverage_tomorrow = weather_tomorrow.get_clouds()
+
+            # Today
+            observation = owm.weather_at_place(extended_location)
+            weather_today = observation.get_weather()
+            weather_today_status = weather_today.get_detailed_status()
+            sunset_time_today = weather_today.get_sunset_time('iso')
+            sunrise_time_today = weather_today.get_sunrise_time('iso')
+
+            temp_today = weather_today.get_temperature(unit=self.temp_unit)
+            temp_today_temp = temp_today['temp']
+            temp_today_temp_max = temp_today['temp_max']
+            temp_today_temp_min = temp_today['temp_min']
+
+            pressure_today = weather_today.get_pressure()
+            pressure_today_press = pressure_today['press']
+            pressure_today_sea_level = pressure_today['sea_level']
+
+            humidity_today = weather_today.get_humidity()
+
+            wind_today= weather_today.get_wind()
+            wind_today_deg = wind_today['deg']
+            wind_today_speed = wind_today['speed']
+
+            snow_today = weather_today.get_snow()
+            rain_today = weather_today.get_rain()
+            clouds_coverage_today = weather_today.get_clouds()
+
+            message = {
+                "location": self.location,
+
+                "weather_today": weather_today_status,
+                "sunset_today_time": sunset_time_today,
+                "sunrise_today_time": sunrise_time_today,
+                "temp_today_temp": temp_today_temp,
+                "temp_today_temp_max": temp_today_temp_max,
+                "temp_today_temp_min": temp_today_temp_min,
+                "pressure_today_press": pressure_today_press,
+                "pressure_today_sea_level": pressure_today_sea_level,
+                "humidity_today": humidity_today,
+                "wind_today_deg": wind_today_deg,
+                "wind_today_speed": wind_today_speed,
+                "snow_today": snow_today,
+                "rain_today": rain_today,
+                "clouds_coverage_today": clouds_coverage_today,
+
+                "weather_tomorrow": weather_tomorrow_status,
+                "sunset_time_tomorrow": sunset_time_tomorrow,
+                "sunrise_time_tomorrow": sunrise_time_tomorrow,
+                "temp_tomorrow_temp": temp_tomorrow_temp,
+                "temp_tomorrow_temp_max": temp_tomorrow_temp_max,
+                "temp_tomorrow_temp_min": temp_tomorrow_temp_min,
+                "pressure_tomorrow_press": pressure_tomorrow_press,
+                "pressure_tomorrow_sea_level": pressure_tomorrow_sea_level,
+                "humidity_tomorrow": humidity_tomorrow,
+                # "wind_tomorrow_deg": wind_tomorrow_deg,
+                "wind_tomorrow_speed": wind_tomorrow_speed,
+                "snow_tomorrow": snow_tomorrow,
+                "rain_tomorrow": rain_tomorrow,
+                "clouds_coverage_tomorrow": clouds_coverage_tomorrow
+            }
+
+            self.say(message)
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.api_key is None:
             raise NotImplementedError("OpenWeatherMap neuron needs an api_key")
-        if location is None:
+        if self.location is None:
             raise NotImplementedError("OpenWeatherMap neuron needs a location")
-        extended_location = location
-        if country is not None:
-            extended_location = location + "," + country
-
-
-        owm = pyowm.OWM(API_key=api_key, language=lang)
-
-        # Tomorrow
-        forecast = owm.daily_forecast(extended_location)
-        tomorrow = pyowm.timeutils.tomorrow()
-        weather_tomorrow = forecast.get_weather_at(tomorrow)
-        weather_tomorrow_status = weather_tomorrow.get_detailed_status()
-        sunset_time_tomorrow = weather_tomorrow.get_sunset_time('iso')
-        sunrise_time_tomorrow = weather_tomorrow.get_sunrise_time('iso')
-
-        temp_tomorrow = weather_tomorrow.get_temperature(unit=temp_unit)
-        temp_tomorrow_temp = temp_tomorrow['day']
-        temp_tomorrow_temp_max = temp_tomorrow['max']
-        temp_tomorrow_temp_min = temp_tomorrow['min']
-
-        pressure_tomorrow = weather_tomorrow.get_pressure()
-        pressure_tomorrow_press = pressure_tomorrow['press']
-        pressure_tomorrow_sea_level = pressure_tomorrow['sea_level']
-
-        humidity_tomorrow = weather_tomorrow.get_humidity()
-
-        wind_tomorrow = weather_tomorrow.get_wind()
-        # wind_tomorrow_deg = wind_tomorrow['deg']
-        wind_tomorrow_speed = wind_tomorrow['speed']
-
-        snow_tomorrow = weather_tomorrow.get_snow()
-        rain_tomorrow = weather_tomorrow.get_rain()
-        clouds_coverage_tomorrow = weather_tomorrow.get_clouds()
-
-        # Today
-        observation = owm.weather_at_place(extended_location)
-        weather_today = observation.get_weather()
-        weather_today_status = weather_today.get_detailed_status()
-        sunset_time_today = weather_today.get_sunset_time('iso')
-        sunrise_time_today = weather_today.get_sunrise_time('iso')
-
-        temp_today = weather_today.get_temperature(unit=temp_unit)
-        temp_today_temp = temp_today['temp']
-        temp_today_temp_max = temp_today['temp_max']
-        temp_today_temp_min = temp_today['temp_min']
-
-        pressure_today = weather_today.get_pressure()
-        pressure_today_press = pressure_today['press']
-        pressure_today_sea_level = pressure_today['sea_level']
-
-        humidity_today = weather_today.get_humidity()
-
-        wind_today= weather_today.get_wind()
-        wind_today_deg = wind_today['deg']
-        wind_today_speed = wind_today['speed']
-
-        snow_today = weather_today.get_snow()
-        rain_today = weather_today.get_rain()
-        clouds_coverage_today = weather_today.get_clouds()
-
-        message = {
-            "location": location,
-
-            "weather_today": weather_today_status,
-            "sunset_today_time": sunset_time_today,
-            "sunrise_today_time": sunrise_time_today,
-            "temp_today_temp": temp_today_temp,
-            "temp_today_temp_max": temp_today_temp_max,
-            "temp_today_temp_min": temp_today_temp_min,
-            "pressure_today_press": pressure_today_press,
-            "pressure_today_sea_level": pressure_today_sea_level,
-            "humidity_today": humidity_today,
-            "wind_today_deg": wind_today_deg,
-            "wind_today_speed": wind_today_speed,
-            "snow_today": snow_today,
-            "rain_today": rain_today,
-            "clouds_coverage_today": clouds_coverage_today,
-
-            "weather_tomorrow": weather_tomorrow_status,
-            "sunset_time_tomorrow": sunset_time_tomorrow,
-            "sunrise_time_tomorrow": sunrise_time_tomorrow,
-            "temp_tomorrow_temp": temp_tomorrow_temp,
-            "temp_tomorrow_temp_max": temp_tomorrow_temp_max,
-            "temp_tomorrow_temp_min": temp_tomorrow_temp_min,
-            "pressure_tomorrow_press": pressure_tomorrow_press,
-            "pressure_tomorrow_sea_level": pressure_tomorrow_sea_level,
-            "humidity_tomorrow": humidity_tomorrow,
-            # "wind_tomorrow_deg": wind_tomorrow_deg,
-            "wind_tomorrow_speed": wind_tomorrow_speed,
-            "snow_tomorrow": snow_tomorrow,
-            "rain_tomorrow": rain_tomorrow,
-            "clouds_coverage_tomorrow": clouds_coverage_tomorrow
-        }
-
-        self.say(message)
-
 
+        return True

+ 20 - 8
neurons/push_message/Push_message.py

@@ -8,8 +8,7 @@ class Push_message(NeuronModule):
     """
     Neuron based on pushetta api. http://www.pushetta.com/
     """
-
-    def __init__(self, message=None, api_key=None, channel_name=None, **kwargs):
+    def __init__(self, **kwargs):
         """
         Send a push message to an android phone via Pushetta API
         :param message: Message to send
@@ -18,13 +17,26 @@ class Push_message(NeuronModule):
         :return:
         """
         super(Push_message, self).__init__(**kwargs)
-        if message is None:
-            raise NotImplementedError("Pushetta neuron needs message to send")
 
-        if api_key is None:
+        self.message = kwargs.get('message', None)
+        self.api_key = kwargs.get('api_key', None)
+        self.channel_name = kwargs.get('channel_name', None)
+
+        # check if parameters have been provided
+        if self._is_parameters_ok():
+            p = Pushetta( self.api_key)
+            p.pushMessage(self.channel_name, self.message)
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.message is None:
+            raise NotImplementedError("Pushetta neuron needs message to send")
+        if self.api_key is None:
             raise NotImplementedError("Pushetta neuron needs api_key")
-        if channel_name is None:
+        if self.channel_name is None:
             raise NotImplementedError("Pushetta neuron needs channel_name")
 
-        p = Pushetta(api_key)
-        p.pushMessage(channel_name, message)
+        return True

+ 49 - 0
neurons/say/README.md

@@ -0,0 +1,49 @@
+# say
+
+## Synopsis
+
+This neuron is the mouth of Kalliope and uses the [TTS](../../Docs/tts.md) to say the given message.
+
+## Options
+
+| parameter | required | default | choices | comment                                |
+|-----------|----------|---------|---------|----------------------------------------|
+| message   | YES      |         |         | A list of messages Kalliope could say  |
+
+## Return Values
+
+No returned values
+
+## Synapses example
+
+Simple example : 
+
+```
+   - name: "Say-hello"
+    neurons:
+      - say:
+          message:
+            - "Hello Sir"
+    signals:
+      - order: "hello"
+```
+
+With a multiple choice list, Kalliope will pick one randomly:
+
+```
+   - name: "Say-hello"
+    neurons:
+      - say:
+          message:
+            - "Hello Sir"
+            - "Welcome Sir"
+            - "Good morning Sir"
+    signals:
+      - order: "hello"
+```
+
+
+## Notes
+
+> **Note:** The neuron does not return any values.
+> **Note:** Kalliope randomly takes a message from the list 

+ 15 - 12
neurons/say/say.py

@@ -1,17 +1,20 @@
-from core.NeuronModule import NeuronModule
-
-
-class NoMessageException(Exception):
-    pass
+from core.NeuronModule import NeuronModule, MissingParameterException
 
 
 class Say(NeuronModule):
     def __init__(self, **kwargs):
         super(Say, self).__init__(**kwargs)
-        # get message to spell out loud
-        message = kwargs.get('message', None)
-        # user must specify a message
-        if message is None:
-            raise NoMessageException("You must specify a message string or a list of messages as parameter")
-        else:
-            self.say(message)
+        self.message = kwargs.get('message', None)
+
+        # check if parameters have been provided
+        if self._is_parameters_ok():
+            self.say(self.message)
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.message is None:
+            raise MissingParameterException("You must specify a message string or a list of messages as parameter")
+        return True

+ 34 - 0
neurons/script/README.md

@@ -0,0 +1,34 @@
+# script
+
+## Synopsis
+
+This neuron runs a script located on the Kalliope system.
+
+## Options
+
+| parameter | required | default | choices | comment                             |
+|-----------|----------|---------|---------|-------------------------------------|
+| path      | YES      |         |         | The path of the script to execute.  |
+
+## Return Values
+
+No returned values
+
+## Synapses example
+
+Simple example : 
+
+```
+  - name: "run-simple-script"
+    neurons:
+      - script:
+          path: "/path/to/script.sh"
+    signals:
+      - order: "Run the script"
+```
+
+
+## Notes
+
+> **Note:** Kalliope must have the rights to run the script.
+> **Note:** Kalliope can be used to grant access to an user with lower rights ... !

+ 18 - 22
neurons/script/script.py

@@ -1,33 +1,29 @@
 import subprocess
 import os
 
-from core.NeuronModule import NeuronModule
-
-
-class ScriptNotFound(Exception):
-    pass
-
-
-class ScriptNotExecutable(Exception):
-    pass
+from core.NeuronModule import NeuronModule, MissingParameterException, InvalidParameterException
 
 
 class Script(NeuronModule):
     def __init__(self, **kwargs):
-        # get message to spell out loud
         super(Script, self).__init__(**kwargs)
-        script_path = kwargs.get('path', "")
+        self.path = kwargs.get("path", None)
 
-        # test that the file exist and is executable
-        if self.is_exe(script_path):
-            p = subprocess.Popen(script_path, stdout=subprocess.PIPE, shell=True)
+        # check parameters
+        if self._is_parameters_ok():
+            p = subprocess.Popen(self.path, stdout=subprocess.PIPE, shell=True)
             (output, err) = p.communicate()
 
-    def is_exe(self, fpath):
-        returned_value = True
-        if not os.path.isfile(fpath):
-            raise ScriptNotFound()
-        if not os.access(fpath, os.X_OK):
-            raise ScriptNotExecutable()
-
-        return returned_value
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.path is None:
+            raise MissingParameterException("You must provide a script path.")
+        if not os.path.isfile(self.path):
+            raise InvalidParameterException("Script not found or is not a file.")
+        if not os.access(self.path, os.X_OK):
+            raise InvalidParameterException("Script not Executable.")
+
+        return True

+ 0 - 0
neurons/shell/Readme.md → neurons/shell/README.md


+ 26 - 21
neurons/shell/shell.py

@@ -28,27 +28,32 @@ class Shell(NeuronModule):
         super(Shell, self).__init__(**kwargs)
 
         # get the command
-        cmd = kwargs.get('cmd', None)
+        self.cmd = kwargs.get('cmd', None)
         # get if the user select a blocking command or not
-        async = kwargs.get('async', False)
-
-        if cmd is None:
+        self.async = kwargs.get('async', False)
+
+        # check parameters
+        if self._is_parameters_ok():
+            # run the command
+            if not self.async:
+                p = subprocess.Popen(self.cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+                (output, err) = p.communicate()
+                message = {
+                    "output": output,
+                    "returncode": p.returncode
+                }
+                self.say(message)
+
+            else:
+                async_shell = AsyncShell(cmd=self.cmd)
+                async_shell.start()
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.cmd is None:
             raise MissingParameterException("cmd parameter required")
 
-        # run the command
-        if not async:
-            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
-            (output, err) = p.communicate()
-            message = {
-                "output": output,
-                "returncode": p.returncode
-            }
-            self.say(message)
-
-        else:
-            async_shell = AsyncShell(cmd=cmd)
-            async_shell.start()
-
-
-
-
+        return True

+ 32 - 0
neurons/sleep/README.md

@@ -0,0 +1,32 @@
+# sleep
+
+## Synopsis
+
+This neuron sleeps the system for a given time in seconds.
+
+## Options
+
+| parameter | required | default | choices | comment                         |
+|-----------|----------|---------|---------|---------------------------------|
+| seconds   | YES      |         |         | The number of seconds to sleep. |
+
+## Return Values
+
+No returned values
+
+## Synapses example
+
+Simple example : 
+
+```
+  - name: "run-simple-sleep"
+    neurons:
+      - sleep:
+          seconds: 60
+    signals:
+      - order: "Wait for me "
+```
+
+
+## Notes
+

+ 14 - 13
neurons/sleep/sleep.py

@@ -1,22 +1,23 @@
 import time
 
-from core.NeuronModule import NeuronModule
-
-
-class NoSecondsException(Exception):
-    pass
+from core.NeuronModule import NeuronModule,  MissingParameterException
 
 
 class Sleep(NeuronModule):
-
     def __init__(self, **kwargs):
-        # get message to spell out loud
         super(Sleep, self).__init__(**kwargs)
-        seconds = kwargs.get('seconds', None)
-        # user must specify a message
-        if seconds is None:
-            raise NoSecondsException("You must set a number of seconds as parameter")
-        time.sleep(seconds)
-
+        self.seconds = kwargs.get('seconds', None)
+
+        # check parameters
+        if self._is_parameters_ok():
+            time.sleep(self.seconds)
+
+        def _is_parameters_ok(self):
+            """
+            Check if received parameters are ok to perform operations in the neuron
+            :return: true if parameters are ok, raise an exception otherwise
+            """
+            if self.seconds is None:
+                raise MissingParameterException("You must set a number of seconds as parameter")
 
 

+ 21 - 15
neurons/tasker_autoremote/tasker_autoremote.py

@@ -13,21 +13,27 @@ class Tasker_autoremote(NeuronModule):
         super(Tasker_autoremote, self).__init__(**kwargs)
 
         # check if parameters have been provided
-        key = kwargs.get('key', None)
-        message = kwargs.get('message', None)
-
-        if key is None:
+        self.key = kwargs.get('key', None)
+        self.message = kwargs.get('message', None)
+
+        # check parameters
+        if self._is_parameters_ok():
+            # create the payload
+            data = {'key': self.key,
+                    'message': self.message}
+            url = "https://autoremotejoaomgcd.appspot.com/sendmessage"
+            # post
+            r = requests.post(url, data=data)
+            logging.debug("Post to tasker automore response: %s" % r.status_code)
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.key is None:
             raise MissingParameterException("key parameter required")
-
-        if message is None:
+        if self.message is None:
             raise MissingParameterException("message parameter required")
 
-        # create the payload
-        data = {'key': key,
-                'message': message}
-        url = "https://autoremotejoaomgcd.appspot.com/sendmessage"
-        # post
-        r = requests.post(url, data=data)
-        logging.debug("Post to tasker automore response: %s" % r.status_code)
-
-
+        return True

+ 31 - 22
neurons/twitter/Twitter.py

@@ -8,34 +8,43 @@ class Twitter(NeuronModule):
 
         super(Twitter, self).__init__(**kwargs)
 
-        consumer_key = kwargs.get('consumer_key', None)
-        consumer_secret = kwargs.get('consumer_secret', None)
-        access_token_key = kwargs.get('access_token_key', None)
-        access_token_secret = kwargs.get('access_token_secret', None)
-        tweet = kwargs.get('tweet', None)
-
-        if consumer_key is None:
+        self.consumer_key = kwargs.get('consumer_key', None)
+        self.consumer_secret = kwargs.get('consumer_secret', None)
+        self.access_token_key = kwargs.get('access_token_key', None)
+        self.access_token_secret = kwargs.get('access_token_secret', None)
+        self.tweet = kwargs.get('tweet', None)
+
+        # check parameters
+        if self._is_parameters_ok():
+            api = twitter.Api(consumer_key=self.consumer_key,
+                              consumer_secret=self.consumer_secret,
+                              access_token_key=self.access_token_key,
+                              access_token_secret=self.access_token_secret)
+
+            status = api.PostUpdate(self.tweet)
+            message = {
+                "tweet" : status.text
+            }
+
+            self.say(message)
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
+        if self.consumer_key is None:
             raise InvalidParameterException("Twitter needs a consumer_key")
-        if consumer_secret is None:
+        if self.consumer_secret is None:
             raise InvalidParameterException("Twitter needs a consumer_secret")
-        if access_token_key is None:
+        if self.access_token_key is None:
             raise InvalidParameterException("Twitter needs an access_token_key")
-        if access_token_secret is None:
+        if self.access_token_secret is None:
             raise InvalidParameterException("Twitter needs and access_token_secret")
-        if tweet is None:
+        if self.tweet is None:
             raise InvalidParameterException("You need to provide something to tweet !")
 
-        api = twitter.Api(consumer_key=consumer_key,
-                          consumer_secret=consumer_secret,
-                          access_token_key=access_token_key,
-                          access_token_secret=access_token_secret)
-
-        status = api.PostUpdate(tweet)
-        message = {
-            "tweet" : status.text
-        }
-
-        self.say(message)
+        return True
 
 
 

+ 28 - 19
neurons/wake_on_lan/Wake_on_lan.py

@@ -12,25 +12,34 @@ class Wake_on_lan(NeuronModule):
     def __init__(self, **kwargs):
         super(Wake_on_lan, self).__init__(**kwargs)
 
-        mac_address = kwargs.get('mac_address', None)
-        broadcast_address = kwargs.get('broadcast_address', '255.255.255.255')
-        port = kwargs.get('port', 9)
-
+        self.mac_address = kwargs.get('mac_address', None)
+        self.broadcast_address = kwargs.get('broadcast_address', '255.255.255.255')
+        self.port = kwargs.get('port', 9)
+
+        # check parameters
+        if self._is_parameters_ok():
+            # convert to unicode for testing
+            broadcast_address_unicode = self.broadcast_address.decode('utf-8')
+            # check the ip address is a valid one
+            ipaddress.ip_address(broadcast_address_unicode)
+
+            logger.debug("Call Wake_on_lan_neuron with parameters: mac_address: %s, broadcast_address: %s, port: %s"
+                         % (self.mac_address, self.broadcast_address, self.port))
+
+            # send the magic packet, the mac address format will be check by the lib
+            wol.send_magic_packet(self.mac_address, ip_address=self.broadcast_address, port=self.port)
+
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        """
         # check we provide a mac address
-        if mac_address is None:
+        if self.mac_address is None:
             raise MissingParameterException("mac_address parameter required")
+            # check the port
+        if type(self.port) is not int:
+            raise InvalidParameterException(
+                "port argument must be an integer. Remove quotes in your configuration.")
 
-        # convert to unicode for testing
-        broadcast_address_unicode = broadcast_address.decode('utf-8')
-        # check the ip address is a valid one
-        ipaddress.ip_address(broadcast_address_unicode)
-
-        # check the port
-        if type(port) is not int:
-            raise InvalidParameterException("port argument must be an integer. Remove quotes in your configuration.")
-
-        logger.debug("Call Wake_on_lan_neuron with parameters: mac_address: %s, broadcast_address: %s, port: %s"
-                     % (mac_address, broadcast_address, port))
-
-        # send the magic packet, the mac address format will be check by the lib
-        # wol.send_magic_packet(mac_address, ip_address=broadcast_address, port=port)
+        return True

+ 1 - 1
test.py

@@ -25,7 +25,7 @@ logger.setLevel(logging.DEBUG)
 #
 brain = BrainLoader.get_brain()
 
-order = "cherche sur Wikipédia bot"
+order = "est-ce que j'ai des emails"
 
 oa = OrderAnalyser(order=order, brain=brain)