Browse Source

Merge branch 'dev' into neurons-OpenWeatherMap

Conflicts:
	neurons/__init__.py
monf 8 years ago
parent
commit
507ecd496e

+ 12 - 11
Docs/neuron_list.md

@@ -2,15 +2,16 @@
 
 A neuron is a module you can use in your synapses. See the [complete neuron documentation](neurons.md) for more information.
 
-| Name                                                | Description                                                                             |
-|-----------------------------------------------------|-----------------------------------------------------------------------------------------|
-| [ansible_task](../neurons/ansible_task/README.md)   | Run an ansible playbook                                                                 |
-| [command](../neurons/command/README.md)             | Run a shell command                                                                     |
-| [gmail_checker](../neurons/gmail_checker/README.md) | Get the number of unread email and their subjects from a gmail account                  |
-| [kill_switch](../neurons/kill_switch/README.md)     | Stop Jarvis process                                                                     |
-| [push_message](../neurons/push_message/README.md)   | Send a push message to a remote device like Android/iOS/Windows Phone or Chrome browser |
-| [say](../neurons/say/README.md)                     | Make Jarvis talk by using TTS                                                           |
-| [script](../neurons/script/README.md)               | Run an executable script                                                                |
-| [sleep](../neurons/sleep/README.md)                 | Make Jarvis sleep for a while before continuing                                         |
-| [systemdate](../neurons/systemdate/README.md)       | Give the local system date and time                                                     |
+| Name                                               | Description                                                                             |
+|----------------------------------------------------|-----------------------------------------------------------------------------------------|
+| [ansible_task](../neurons/ansible_task/)           | Run an ansible playbook                                                                 |
+| [command](../neurons/command/)                     | Run a shell command                                                                     |
+| [gmail_checker](../neurons/gmail_checker/)         | Get the number of unread email and their subjects from a gmail account                  |
+| [kill_switch](../neurons/kill_switch/)             | Stop Jarvis process                                                                     |
+| [push_message](../neurons/push_message/)           | Send a push message to a remote device like Android/iOS/Windows Phone or Chrome browser |
+| [say](../neurons/say/)                             | Make Jarvis talk by using TTS                                                           |
+| [script](../neurons/script/)                       | Run an executable script                                                                |
+| [sleep](../neurons/sleep/)                         | Make Jarvis sleep for a while before continuing                                         |
+| [systemdate](../neurons/systemdate/)               | Give the local system date and time                                                     |
+| [tasker_autoremote](../neurons/tasker_autoremote/) | Send a message to Android tasker app                                                    |
 

+ 10 - 4
brain.yml

@@ -52,16 +52,13 @@
           tts: "voxygen"
           say_template:
             - "il est {{ hours }} heure et {{ minutes }} minute"
-          cache: False
     signals:
       - order: "quelle heure est-il"
 
   - name: "Say local date from template"
     neurons:
       - systemdate:
-          file_template: fr_systemdate_template_example.j2
-          tts: "voxygen"
-          cache: False
+          file_template: en_systemdate_template_example.j2
     signals:
       - order: "test heure"
 
@@ -155,3 +152,12 @@
       - order: "I would like to hear the song {{ music_name }}"
       - order: "I would like to hear {{ artist_name }}"
 
+  - name: "find my phone"
+    neurons:
+      - say:
+          message: "Je fais sonner le téléphone, monsieur"
+      - tasker_autoremote:
+          key: "APA91bqmY"
+          message: "lost"
+    signals:
+      - order: "où est mon téléphone"

+ 8 - 0
core/NeuronModule.py

@@ -3,6 +3,7 @@ import logging
 import os
 import random
 
+import sys
 from jinja2 import Template
 
 from core.Utils import Utils
@@ -12,6 +13,10 @@ logging.basicConfig()
 logger = logging.getLogger("kalliope")
 
 
+class MissingParameterException(Exception):
+    pass
+
+
 class NoTemplateException(Exception):
     pass
 
@@ -128,6 +133,9 @@ class NeuronModule(object):
                 t = Template(self.say_template)
                 returned_message = t.render(**message_dict)
 
+            # trick to remobe unicode problem when loading jinja template with non ascii char
+            reload(sys)
+            sys.setdefaultencoding('utf-8')
             # the user choose a file_template option
             if self.file_template is not None:  # the user choose a file_template option
                 real_file_template_path = "templates/%s" % self.file_template

+ 1 - 0
neurons/__init__.py

@@ -8,3 +8,4 @@ from systemdate import Systemdate
 from gmail_checker import Gmail_checker
 from push_message import Push_message
 from Openweathermap import Openweathermap
+from tasker_autoremote import Tasker_autoremote

+ 117 - 0
neurons/systemdate/README.md

@@ -0,0 +1,117 @@
+# Systemdate
+
+## Synopsis
+
+Give the current time from the system where Kalliope is installed. Return a dict of parameters that can be used in a template.
+
+## Options
+
+| parameter     | required | default | choices     | comment                                                               |
+|---------------|-----------|---------|-------------|-----------------------------------------------------------------------|
+| say_template  | no        |         |             | Say template used to make Kalliope speak out loud returned parameters |
+| file_template | no        |         |             | Like a say_template but from a file for complex usage                 |
+| cache         | no        | FALSE   | True, False | Should be set to False as audio output will changes at every minute   |
+
+
+## Return Values
+
+| name      | description                                       | type   | sample |
+|-----------|---------------------------------------------------|--------|--------|
+| hours     | Hour (24-hour clock) as a decimal number [00,23]. | string | 22     |
+| minutes   | Minute as a decimal number [00,59].               | string | 54     |
+| weekday   | Weekday as a decimal number [0(Sunday),6].        | string | 4      |
+| month     | Month as a decimal number [01,12].                | string | 4      |
+| day_month | Day of the month as a decimal number [01,31].     | string | 12     |
+| year      | Year with century as a decimal number             | string | 2016   |
+
+
+## Synapses example
+
+Simple synapse that give the current time with only hours and minutes
+```
+ - name: "time"
+    neurons:
+      - systemdate:
+          say_template:
+            - "It' {{ hours }} hours and {{ minutes }} minutes"
+    signals:
+      - order: "what time is it"
+```
+
+Synapse that give complete date and time with a template file.
+```
+ - name: "time"
+    neurons:
+      - systemdate:
+          file_template: en_systemdate_template_example.j2            
+    signals:
+      - order: "what time is it"
+```
+
+
+## Templates example 
+Following examples are available in the [neuron directory](template_examples/).
+
+This template will transcribe received numbers from the neuron into natural language
+```
+"It's {{ hours }} hours and {{ minutes }} minutes
+```
+
+This template, which it must be placed in a file_template, will give the complete date and time.
+```
+{% set day_of_week = {
+    "0": "sunday",
+    "1": "monday",
+    "2": "tuesday",
+    "3": "wednesday",
+    "4": "thursday",
+    "5": "friday",
+    "6": "saturday"
+    }[weekday] | default("")
+-%}
+
+{% set month_word = {"1": "january", "2": "february", "3": "march", "4": "april", "5": "may", "6": "june", "7": "july", "8": "august", "9": "september", "10": "october", "11": "november", "12": "december"}[month] | default("") -%}
+
+{% set day_month_formated = {
+    "1": "first",
+    "2": "second",
+    "3": "third",
+    "4": "fourth",
+    "5": "fifth",
+    "6": "sixth",
+    "7": "seventh",
+    "8": "eighth",
+    "9": "ninth",
+    "10": "tenth",
+    "11": "eleventh",
+    "12": "twelfth",
+    "13": "thirteenth",
+    "14": "fourteenth",
+    "15": "fifteenth",
+    "16": "sixteenth",
+    "17": "seventeenth",
+    "18": "eighteenth",
+    "19": "nineteenth",
+    "20": "twentieth",
+    "21": "twenty-first",
+    "22": "twenty-second",
+    "23": "twenty-third",
+    "24": "twenty-fourth",
+    "25": "twenty-fifth",
+    "26": "twenty-sixth",
+    "27": "twenty-seventh",
+    "28": "twenty-eighth",
+    "29": "twenty-ninth",
+    "30": "thirtieth",
+    "31": "thirty-first",
+
+}[day_month] | default("") -%}
+
+It' {{ hours }} hours and {{ minutes }} minutes.
+We are the {{ day_of_week }} {{ month_word }} the {{ day_month_formated }} {{ year }}
+```
+
+## Notes
+
+> **Note:** As the neuron is based on the local system date, this last must be well configured. A good practice is the installation and configuration of a NTP client
+ to synchronize the time on your Linux system with a centralized NTP server.

+ 17 - 6
neurons/systemdate/systemdate.py

@@ -6,18 +6,29 @@ from core.NeuronModule import NeuronModule
 
 class Systemdate(NeuronModule):
     def __init__(self, **kwargs):
-        super(Systemdate, self).__init__(**kwargs)
+        # get the cache if set by the user, if not, set it to false as it is not necessary
+        cache = kwargs.get('cache', None)
+        if cache is None:
+            cache = False
+        super(Systemdate, self).__init__(cache=cache, **kwargs)
 
-        # get hours and minutes
 
-        hour = time.strftime("%H")
-        minute = time.strftime("%M")
 
+        # local time and date
+        hour = time.strftime("%H")          # Hour (24-hour clock) as a decimal number [00,23].
+        minute = time.strftime("%M")        # Minute as a decimal number [00,59].
+        weekday = time.strftime("%w")       # Weekday as a decimal number [0(Sunday),6].
+        day_month = time.strftime("%d")     # Day of the month as a decimal number [01,31].
+        month = time.strftime("%m")         # Month as a decimal number [01,12].
+        year = time.strftime("%Y")          # Year with century as a decimal number. E.g: 2016
 
         message = {
             "hours": hour,
             "minutes": minute,
+            "weekday": weekday,
+            "month": month,
+            "day_month": day_month,
+            "year": year
         }
-        if "insulte" in kwargs:
-            message["insulte"] = kwargs.get("insulte")
+        
         self.say(message)

+ 0 - 1
neurons/systemdate/template/fr_template2.j2

@@ -1 +0,0 @@
-{{ hours }} heures et {{ minutes }} minutes précisément

+ 1 - 0
neurons/systemdate/template_examples/en_template1.j2

@@ -0,0 +1 @@
+It's {{ hours }} hours and {{ minutes }} minutes.

+ 12 - 0
neurons/systemdate/template_examples/en_template2.j2

@@ -0,0 +1,12 @@
+{% set day_of_week = {"0": "sunday", "1": "monday", "2": "tuesday", "3": "wednesday", "4": "thursday", "5": "friday", "6": "saturday"}[weekday] | default("") -%}
+{% set month_word = {"1": "january", "2": "february", "3": "march", "4": "april", "5": "may", "6": "june", "7": "july", "8": "august", "9": "september", "10": "october", "11": "november", "12": "december"}[month] | default("") -%}
+
+{% set day_month_formated = {
+{
+"15": "fifteenth"
+}
+}
+[day_month] | default("") -%}
+
+It' {{ hours }} hours and {{ minutes }} minutes.
+We are the {{ day_of_week }} {{ month_word }} the {{ day_month_formated }} {{ year }}

+ 0 - 0
neurons/systemdate/template/fr_template1.j2 → neurons/systemdate/template_examples/fr_template1.j2


+ 5 - 0
neurons/systemdate/template_examples/fr_template2.j2

@@ -0,0 +1,5 @@
+{% set day_of_week = {"0": "dimanche", "1": "lundi", "2": "mardi", "3": "mercredi", "4": "jeudi", "5": "vendredi", "6": "samedi"}[weekday] | default("") -%}
+{% set month_word = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"}[month] | default("") -%}
+
+Il est {{ hours }} heures et {{ minutes }} minutes.
+Nous sommes le {{ day_of_week }} {{ day_month }} {{ month_word }} {{ year }}

+ 83 - 0
neurons/tasker_autoremote/Readme.md

@@ -0,0 +1,83 @@
+# Tasker autoremote
+
+## Synopsis
+
+[Tasker](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm) is an application for Android which performs 
+tasks (sets of actions) based on contexts (application, time, date, location, event, gesture) in user-defined profiles or in 
+clickable or timer home screen widgets.
+
+[Tasker autoremote](https://play.google.com/store/apps/details?id=com.joaomgcd.autoremote&hl=fr) is a plugin for Tasker that allow 
+the program to receive push message from the cloud as profile.
+
+This is how it works:
+- Send an AutoRemote message from Kalliope
+- Setup an AutoRemote profile in Tasker to react to the message
+- Do whatever you like with that message!
+
+The example usage is a "find my phone" task. 
+You could send a "Where are you?" message to your phone, and have Tasker respond with a repetitive "I'm here! I'm here!" 
+or play a music.
+
+
+## Options
+
+| parameter | required | default | choices | comment                                                       |
+|-----------|----------|---------|---------|---------------------------------------------------------------|
+| key       | yes      |         |         | API key. Can be found in your personal URL given by the app.  |
+| message   | yes      |         |         | Message to send to your phone                                 |
+
+## Return Values
+
+None
+
+## Synapses example
+
+Description of what the synapse will do
+```
+ - name: "find my phone"
+    neurons:
+      - say:
+          message: "I'll make your phone ringing, sir"
+      - tasker_autoremote:
+          key: "MY_VERY_LONG_KEY"
+          message: "lost"
+    signals:
+      - order: "where is my phone"
+```
+
+
+## Notes
+
+### How to create a find my phone task
+This walk through will show you how to send a message to your phone so that even if it is set to silent, 
+will play any music file at full volume so you can find your phone if you have lost it in the couch.
+
+First, create a task, that you could call "start_ringing" that will perform:
+- Disable the silent mode
+- Set media volume to the maximum value
+- Play a local music
+
+![task play music](images/task_play_music.png)
+
+Then, create a new task with just one action:
+- Stop the music
+
+![task stop music](images/task_stop_music.png)
+
+Create the input profile. 
+- create a context of type Event > Plugin > Autoremote
+- Set the word you want
+- Attach the event to the task "start_ringing"
+
+![task stop music](images/profile_auto_remote.png)
+
+Finally, create a event, to stop the music when we unlock the phone
+- create a context of type Event > Display > Display Unlocked
+- Attach the event to the stop that stop the music
+
+![task stop music](images/profile_display_unlocked.png)
+
+Exit Tasker with the exit menu to be sure all events and task have been saved.
+
+
+ 

+ 1 - 0
neurons/tasker_autoremote/__init__.py

@@ -0,0 +1 @@
+from tasker_autoremote import Tasker_autoremote

BIN
neurons/tasker_autoremote/images/profile_auto_remote.png


BIN
neurons/tasker_autoremote/images/profile_display_unlocked.png


BIN
neurons/tasker_autoremote/images/task_play_music.png


BIN
neurons/tasker_autoremote/images/task_stop_music.png


+ 33 - 0
neurons/tasker_autoremote/tasker_autoremote.py

@@ -0,0 +1,33 @@
+import logging
+
+import requests
+
+from core.NeuronModule import NeuronModule, MissingParameterException
+
+logging.basicConfig()
+logger = logging.getLogger("kalliope")
+
+
+class Tasker_autoremote(NeuronModule):
+    def __init__(self, **kwargs):
+        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:
+            raise MissingParameterException("key parameter required")
+
+        if 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)
+
+

+ 50 - 0
templates/en_systemdate_template_example.j2

@@ -0,0 +1,50 @@
+{% set day_of_week = {
+    "0": "sunday",
+    "1": "monday",
+    "2": "tuesday",
+    "3": "wednesday",
+    "4": "thursday",
+    "5": "friday",
+    "6": "saturday"
+    }[weekday] | default("")
+-%}
+
+{% set month_word = {"1": "january", "2": "february", "3": "march", "4": "april", "5": "may", "6": "june", "7": "july", "8": "august", "9": "september", "10": "october", "11": "november", "12": "december"}[month] | default("") -%}
+
+{% set day_month_formated = {
+    "1": "first",
+    "2": "second",
+    "3": "third",
+    "4": "fourth",
+    "5": "fifth",
+    "6": "sixth",
+    "7": "seventh",
+    "8": "eighth",
+    "9": "ninth",
+    "10": "tenth",
+    "11": "eleventh",
+    "12": "twelfth",
+    "13": "thirteenth",
+    "14": "fourteenth",
+    "15": "fifteenth",
+    "16": "sixteenth",
+    "17": "seventeenth",
+    "18": "eighteenth",
+    "19": "nineteenth",
+    "20": "twentieth",
+    "21": "twenty-first",
+    "22": "twenty-second",
+    "23": "twenty-third",
+    "24": "twenty-fourth",
+    "25": "twenty-fifth",
+    "26": "twenty-sixth",
+    "27": "twenty-seventh",
+    "28": "twenty-eighth",
+    "29": "twenty-ninth",
+    "30": "thirtieth",
+    "31": "thirty-first",
+
+}[day_month] | default("") -%}
+
+It' {{ hours }} hours and {{ minutes }} minutes.
+We are the {{ day_of_week }} {{ month_word }} the {{ day_month_formated }} {{ year }}

+ 5 - 1
templates/fr_systemdate_template_example.j2

@@ -1 +1,5 @@
-ma montre indique {{ hours }} heures et {{ minutes }} minutes
+{% set day_of_week = {"0": "dimanche", "1": "lundi", "2": "mardi", "3": "mercredi", "4": "jeudi", "5": "vendredi", "6": "samedi"}[weekday] | default("") -%}
+{% set month_word = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"}[month] | default("") -%}
+
+Il est {{ hours }} heures et {{ minutes }} minutes.
+Nous sommes le {{ day_of_week }} {{ day_month }} {{ month_word }} {{ year }}

+ 9 - 58
test.py

@@ -4,71 +4,22 @@ import re
 from collections import Counter
 
 from core import OrderAnalyser
+from neurons import Systemdate
+from neurons.tasker_autoremote.tasker_autoremote import Tasker_autoremote
+
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
 logger.setLevel(logging.DEBUG)
 
 
-# This does not work because of different encoding when using accent
-from core import OrderAnalyser
-# order = "kalliope régle le réveil pour sept heures et vingt minutes"
-# order = "mais nous de la musique"
 
-order = "arrête la musique"
-# order = order.decode('utf-8')
-# print type(order)
+order = "test heure"
 oa = OrderAnalyser(order)
-
 oa.start()
 
 
-# user_said = "kalliope régle le réveil pour sept heures et pour vingts minutes"
-#
-# order = "régle le réveil pour {{ hour }} heures et pour {{ minute }} minutes"
-#
-#
-# def counterSubset(list1, list2):
-#     """
-#     check if the number of occurrences matches
-#     :param list1:
-#     :param list2:
-#     :return:
-#     """
-#     c1, c2 = Counter(list1), Counter(list2)
-#     for k, n in c1.items():
-#         if n > c2[k]:
-#             return False
-#     return True
-#
-#
-# def _spelt_order_match_brain_order_via_table(order_to_analyse, user_said):
-#     list_word_user_said = user_said.split()
-#     split_order_without_bracket = _get_list_word_without_bracket(order_to_analyse)
-#
-#     number_of_word_in_order = len(split_order_without_bracket)
-#     # if all words in the list of what the user said in in the list of word in the order
-#     # return len(set(split_order_without_bracket).intersection(list_word_user_said)) == number_of_word_in_order
-#     return counterSubset(split_order_without_bracket, list_word_user_said)
-#
-#
-# def _get_list_word_without_bracket(order):
-#     """
-#     Get an order with bracket inside like: "hello my name is {{ name }}.
-#     return a list of string without bracket like ["hello", "my", "name", "is"]
-#     :param order: sentence to split
-#     :return: list of string without bracket
-#     """
-#     pattern = r"((?:{{\s*)[\w\.]+(?:\s*}}))"
-#     # find everything like {{ word }}
-#     matches = re.findall(pattern, order)
-#     for match in matches:
-#         order = order.replace(match, "")
-#     # then split
-#     split_order = order.split()
-#     return split_order
-#
-# # main test
-# if _spelt_order_match_brain_order_via_table(order, user_said):
-#     print "order matched"
-# else:
-#     print "order does not match"
+
+
+
+
+