#################################################################################
# Sample platypush configuration file.
# Edit it and copy it to /etc/platypush/config.yaml for system installation or to
# ~/.config/platypush/config.yaml for user installation (recommended).
#################################################################################

# --
# include directive example
# --
#
# You can split your configuration over multiple files
# and use the include directive to import them in your configuration.
# Relative paths are also supported, and computed using the config.yaml
# installation directory as base folder. Symlinks are also supported.
#
# Using multiple files is encouraged in the case of large configurations
# that can easily end up in a messy config.yaml file, as they help you
# keep your configuration more organized.
include:
    - include/logging.yaml
    - include/media.yaml
    - include/sensors.yaml

# platypush logs on stdout by default. You can use the logging section to specify
# an alternative file or change the logging level.
logging:
    filename: ~/.local/log/platypush/platypush.log
    level: INFO

# The device_id is used by many components of platypush and it should uniquely
# identify a device in your network. If nothing is specified then the hostname
# will be used.
device_id: myname

## --
## Plugin configuration examples
## --
#
# Plugins configuration is very straightforward. Each plugin is mapped to
# a plugin class. The methods of the class with @action annotation will
# be exported as runnable actions, while the __init__ parameters are
# configuration attributes that you can initialize in your config.yaml.
# Plugin classes are documented at https://docs.platypush.tech/en/latest/plugins.html
#
# In this example we'll configure the light.hue plugin, see
# https://docs.platypush.tech/en/latest/platypush/plugins/light.hue.html
# for reference. You can easily install the required dependencies for the plugin through
# pip install 'platypush[hue]'
light.hue:
    # IP address or hostname of the Hue bridge
    bridge: 192.168.1.10
    # Groups that will be handled by default if nothing is specified on the request
    groups:
        - Living Room

# Example configuration of music.mpd plugin, see
# https://docs.platypush.tech/en/latest/platypush/plugins/music.mpd.html
# You can easily install the dependencies through pip install 'platypush[mpd]'
music.mpd:
    host: localhost
    port: 6600

# Example configuration of media.chromecast plugin, see
# https://docs.platypush.tech/en/latest/platypush/plugins/media.chromecast.html
# You can easily install the dependencies through pip install 'platypush[chromecast]'
media.chromecast:
    chromecast: Living Room TV

# Plugins with empty configuration can also be explicitly enabled by specifying
# enabled=True or disabled=False (it's a good practice if you want the
# corresponding web panel to be enabled, if available)
camera:
    enabled: True

# Support for last.fm scrobbling. Install dependencies with 'pip install "platypush[lastfm]"
lastfm:
    api_key: your_api_key
    api_secret: your_api_secret
    username: your_username
    password: your_password

# Support for calendars - in this case Google and Facebook calendars
# Installing the dependencies: pip install 'platypush[ical,google]'
calendar:
    calendars:
        -
            type: platypush.plugins.google.calendar.GoogleCalendarPlugin
        -
            type: platypush.plugins.calendar.ical.CalendarIcalPlugin
            url: https://www.facebook.com/events/ical/upcoming/?uid=your_user_id&key=your_key

## --
## Backends configuration examples
## --
#
# Backends are basically threads that run in the background and listen for something
# to happen and either trigger events or provide additional services on top of platypush.
# Just like plugins, backends are classes whose configuration matches one-to-one the
# supported parameters on the __init__ methods. You can check the documentation for the
# available backends here: https://docs.platypush.tech/en/latest/backends.html.
# Moreover, most of the backends will generate events that you can react to through custom
# event hooks. Check here for the events documentation:
# https://docs.platypush.tech/en/latest/events.html
#
# You may usually want to enable the HTTP backend, as it provides many useful features on
# top of platypush. Among those:
#
# - Expose the /execute endpoint, that allows you to send requests to platypush through a
#   JSON-RPC interface.
# - Web panel, one of the key additiona features of platypush. Many plugins will expose web
#   panel tabs for e.g. accessing and controlling lights, music, media and sensors.
# - Dashboard: platypush can be configured to show a custom dashboard on your screens with
#   e.g. music platypush and weather info, news, upcoming calendar events and photo carousel.
# - Streaming support - the HTTP backend makes it possible to stream local media to other
#   devices - e.g. Chromecasts and external browsers.
#
# To install the HTTP backend dependencies simply run 'pip install "platypush[http]"'
backend.http:
    # Listening port
    port: 8008

    # Through resource_dirs you can specify external folders whose content can be accessed on
    # the web server through a custom URL. In the case below we have a Dropbox folder containing
    # our pictures and we mount it to the '/carousel' endpoint.
    resource_dirs:
        carousel: ~/Dropbox/Photos/carousel

    # Dashboard configuration. The dashboard is a collection of widgets and it's organized in
    # multiple rows. Each rows can be split in 12 columns. Therefore 'columns: 12' will make
    # a widget span over the whole row, while 'columns: 6' will make a widget take half the
    # horizontal space of a column.
    dashboard:
        widgets:
            -
                widget: calendar
                columns: 6
            -
                widget: music
                columns: 3
            -
                widget: date-time-weather
                columns: 3
            -
                widget: image-carousel
                columns: 6
                images_path: ~/Dropbox/Photos/carousel
                refresh_seconds: 15
            -
                widget: rss-news
                # Requires backend.http.poll to be enabled with some
                # RSS sources and write them to sqlite db
                columns: 6
                limit: 25
                db: "sqlite:////home/user/.local/share/platypush/feeds/rss.db"

# The HTTP poll backend is a versatile backend that can monitor for HTTP-based resources and
# trigger events whenever new entries are available. In the example below we show how to use
# the backend to listen for changes on a set of RSS feeds. New content will be stored by default
# on a SQLite database under ~/.local/share/platypush/feeds/rss.db.
# Install the required dependencies through 'pip install "platypush[rss,db]"'
backend.http.poll:
    requests:
        -
            # HTTP poll type (RSS)
            type: platypush.backend.http.request.rss.RssUpdates
            # Remote URL
            url: http://www.theguardian.com/rss/world
            # Custom title
            title: The Guardian - World News
            # How often we should check for changes
            poll_seconds: 600
            # Maximum number of new entries to be processed
            max_entries: 10
        -
            type: platypush.backend.http.request.rss.RssUpdates
            url: http://www.physorg.com/rss-feed
            title: Phys.org
            poll_seconds: 600
            max_entries: 10
        -
            type: platypush.backend.http.request.rss.RssUpdates
            url: http://feeds.feedburner.com/Techcrunch
            title: Tech Crunch
            poll_seconds: 600
            max_entries: 10
        -
            type: platypush.backend.http.request.rss.RssUpdates
            url: http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml
            title: The New York Times
            poll_seconds: 300
            max_entries: 10

# MQTT backend. Installed required dependencies through 'pip install "platypush[mqtt]"'
backend.mqtt:
    # Remote MQTT server IP or hostname
    host: mqtt-server
    # By default the backend will listen for messages on the platypush_bus_mq/device_id
    # topic, but you can change the prefix using the topic attribute
    topic: my_platypush_bus

# Raw TCP socket backend. It can run commands sent as JSON over telnet or netcat
backend.tcp:
    port: 3333

# Websocket backend. Install required dependencies through 'pip install "platypush[http]"'
backend.websocket:
    port: 8765

## --
## Assistant configuration examples
## --
#
# Both Google Assistant and Alexa voice assistant interfaces are supported by platypush.
# You can easily make your custom voice assistant with a RaspberryPi and a USB microphone,
# or on your laptop. Note however that the Alexa integration is still experimental
# (mostly because of glitches and bugs on the avs package provided by Amazon), while the
# Google Assistant support should be more robust. The recommended way of triggering a
# hotword ('OK Google', 'Alexa' or any custom hotword you like) is through the snowboy
# backend (install it through 'pip install "platypush[hotword]"'). You can download custom
# voice model files (.umdl) from https://snowboy.kitt.ai.
backend.assistant.snowboy:
    # Microphone audio gain
    audio_gain: 1.1

    models:
        # "Computer" hotword model
        computer:
            # UMDL file path
            voice_model_file: ~/.local/share/snowboy/models/computer.umdl
            # Plugin to use (Google Assistant)
            assistant_plugin: assistant.google.pushtotalk
            # Language assistant (Italian)
            assistant_language: it-IT
            # Sound to play when the hotword is detected
            detect_sound: ~/.local/share/sounds/hotword.wav
            # Model sensitivity
            sensitivity: 0.4
        # "OK Google" hotword model
        ok_google:
            voice_model_file: ~/.local/share/snowboy/models/OK Google.pmdl
            assistant_plugin: assistant.google.pushtotalk
            assistant_language: en-US
            detect_sound: ~/.local/share/sounds/sci-fi/PremiumBeat_0013_cursor_selection_16.wav
            sensitivity: 0.4
        # "Alexa" voice model
        alexa:
            voice_model_file: ~/.local/share/snowboy/models/Alexa.pmdl
            assistant_plugin: assistant.echo
            assistant_language: en-US
            detect_sound: ~/.local/share/sounds/sci-fi/PremiumBeat_0013_cursor_selection_16.wav
            sensitivity: 0.5

# Install Alexa dependencies with 'pip install "platypush[alexa]"'
assistant.echo:
    audio_player: mplayer

# Install Google Assistant dependencies with 'pip install "platypush[google-assistant]"'
assistant.google.pushtotalk:
    language: en-US

## --
## Procedure examples
## --
#
# Procedures are lists of actions that can be executed synchronously (default) or in parallel
# (procedure.async. prefix). Basic flow control operators (if/else/for) are also available.
# You can also access Python variables and evaluate Python expressions by using the ${} expressions.
# The 'context' special variable is a name->value dictionary containing the items returned from
# previous actions - for example if an action returned '{"status": "ok", "temperature":21.5}' then
# the following actions can access those variables through ${status} and ${temperature} respectively,
# and you can also add things like '- if ${temperature > 20.0}' or '- for ${temp in temperature_values}'.
# Alternatively, you can access those variable also through ${context.get('status')} or ${context.get('temperature')}.
# Other special variables that you can use in your procedures:
#
# - output: Will contain the parsed output of the previous action
# - errors: Will contain the errors of the previous action
# - event: If the procedure is executed within an event hook, it contains the event that triggered the hook
#
# An example procedure that can be called when you arrive home. You can run this procedure by sending a JSON
# message like this on whichever backend you like (HTTP, websocket, TCP, Redis, MQTT, Node-RED, Pushbullet...)
# {"type":"request", "action":"procedure.at_home"}
# You can for instance install Tasker+AutoLocation on your mobile and send this message whenever you enter
# your home area.
procedure.at_home:
    # Set the db variable HOME to 1
    - action: variable.set
      args:
          HOME: 1

    # Check the luminosity level from a connected LTR559 sensor
    - action: gpio.sensor.ltr559.get_data

    # If it's below a certain threshold turn on the lights
    - if ${int(light or 0) < 110}:
        - action: light.hue.on

    # Say a welcome home message. Install dependencies through 'pip install "platypush[google-tts]"'
    - action: tts.google.say
      args:
          text: Welcome home

    # Start the music
    - action: music.mpd.play

# Procedure that will be execute when you're outside of home
procedure.outside_home:
    # Unset the db variable HOME
    - action: variable.unset
      args:
          name: HOME

    # Stop the music
    - action: music.mpd.stop

    # Turn off the lights
    - action: light.hue.off

    # Start the camera streaming. Install the Pi Camera dependencies through
    # 'pip install "platypush[picamera]"'
    - action: camera.pi.start_streaming
      args:
          listen_port: 2222

# Procedures can also take optional arguments. The example below show a
# generic procedure to send a request to another platypush host over MQTT
# given target, action and args
procedure.send_request(target, action, args):
    - action: mqtt.send_message
      args:
          topic: my_platypush_bus/${target}
          host: mqtt-server
          port: 1883
          msg:
              type: request
              target: ${target}
              action: ${action}
              args: "${context.get('args', {}}"

## --
## Event hook examples
## --
#
# Event hooks are procedures that are run when a certain condition is met.
# Check the documentation of the backends to see which events they can trigger.
# An event hook consists of two parts: an 'if' field that specifies on which
# event the hook will be triggered (type and attributes content), and a 'then'
# field that uses the same syntax as procedures to specify a list of actions to
# execute when the event is matched.
#
# The example below plays the music on mpd/mopidy when your voice assistant
# triggers a speech recognized event with "play the music" content.
event.hook.PlayMusicAssistantCommand:
    if:
        type: platypush.message.event.assistant.SpeechRecognizedEvent
        # Note that basic regexes are supported, so the hook will be triggered
        # both if you say "play the music" and "play music"
        phrase: "play (the)? music"
    then:
        - action: music.mpd.play

# This will turn on the lights when you say "turn on the lights"
event.hook.TurnOnLightsCommand:
    if:
        type: platypush.message.event.assistant.SpeechRecognizedEvent
        phrase: "turn on (the)? lights?"
    then:
        - action: light.hue.on

# This will play a song by a specified artist
event.hook.SearchSongVoiceCommand:
    if:
        type: platypush.message.event.assistant.SpeechRecognizedEvent
        # Note that you can use the ${} operator in event matching to
        # extract part of the matched string into context variables that
        # can be accessed in your event hook.
        phrase: "play ${title} by ${artist}"
    then:
        - action: music.mpd.clear
        - action: music.mpd.search
          args:
              filter:
                  - artist
                  - ${artist}
                  - any
                  - ${title}

        # Play the first search result
        - action: music.mpd.play
          args:
              resource: ${output[0]['file']}

# This event will scrobble newly listened tracks on mpd/mopidy to last.fm
event.hook.ScrobbleNewTrack:
    if:
        type: platypush.message.event.music.NewPlayingTrackEvent
    then:
        - action: lastfm.scrobble
          args:
              artist: ${track['artist']}
              title: ${track['title']}

        - action: lastfm.update_now_playing
          args:
              artist: ${track['artist']}
              title: ${track['title']}

## --
## Cron examples
## --
#
# Cronjobs allow you to execute procedures at periodic intervals.
# Standard UNIX cron syntax is supported, plus an optional 6th indicator
# at the end of the expression to run jobs with second granularity.
# The example below executes a script at intervals of 1 minute.
cron.TestCron:
    cron_expression: '* * * * *'
    actions:
        - action: shell.exec
          args:
              cmd: ~/bin/myscript.sh

