From c69f97c0a56f5bf53e3ed55418d6e314dc4241ae Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Mon, 4 Sep 2023 02:22:46 +0200 Subject: [PATCH] Updated default config.yaml. The new configuration: - Enables `backend.http` by default - Removes the extra `config.auto.yaml` dependency - Includes many more examples, lots of updates for existing examples, and extensive comments. --- examples/conf/config.yaml | 379 ---------- examples/config/config.yaml | 1 + examples/{conf => config}/dashboard.xml | 0 examples/{conf => config}/hook.py | 16 +- platypush/builder/_base.py | 2 +- platypush/config/config.auto.yaml | 6 - platypush/config/config.yaml | 922 +++++++++++++++++++++++- 7 files changed, 933 insertions(+), 393 deletions(-) delete mode 100644 examples/conf/config.yaml create mode 120000 examples/config/config.yaml rename examples/{conf => config}/dashboard.xml (100%) rename examples/{conf => config}/hook.py (88%) delete mode 100644 platypush/config/config.auto.yaml diff --git a/examples/conf/config.yaml b/examples/conf/config.yaml deleted file mode 100644 index 5c9561a5..00000000 --- a/examples/conf/config.yaml +++ /dev/null @@ -1,379 +0,0 @@ -################################################################################# -# 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: my_device - -## -- -## 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.pi: - enabled: True - -# 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: /mnt/hd/photos/carousel - -# 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: - - type: platypush.backend.http.request.rss.RssUpdates # HTTP poll type (RSS) - # 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: MyBus - -# Raw TCP socket backend. It can run commands sent as JSON over telnet or netcat -#backend.tcp: -# port: 3333 - -## -- -## 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-legacy]"' -assistant.google: - enabled: True - -backend.assistant.google: - enabled: True - -## -- -## 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: platypush_bus_mq/${target} - host: mqtt-server - port: 1883 - msg: - type: request - target: ${target} - action: ${action} - args: ${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} - title: ${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 - diff --git a/examples/config/config.yaml b/examples/config/config.yaml new file mode 120000 index 00000000..6e3e6226 --- /dev/null +++ b/examples/config/config.yaml @@ -0,0 +1 @@ +../../platypush/config/config.yaml \ No newline at end of file diff --git a/examples/conf/dashboard.xml b/examples/config/dashboard.xml similarity index 100% rename from examples/conf/dashboard.xml rename to examples/config/dashboard.xml diff --git a/examples/conf/hook.py b/examples/config/hook.py similarity index 88% rename from examples/conf/hook.py rename to examples/config/hook.py index 2ad765f4..2f4081b8 100644 --- a/examples/conf/hook.py +++ b/examples/config/hook.py @@ -12,7 +12,10 @@ from platypush.utils import run from platypush.event.hook import hook # Event types that you want to react to -from platypush.message.event.assistant import ConversationStartEvent, SpeechRecognizedEvent +from platypush.message.event.assistant import ( + ConversationStartEvent, + SpeechRecognizedEvent, +) @hook(SpeechRecognizedEvent, phrase='play ${title} by ${artist}') @@ -23,10 +26,13 @@ def on_music_play_command(event, title=None, artist=None, **context): Note that in this specific case we can leverage the token-extraction feature of SpeechRecognizedEvent through ${} that operates on regex-like principles to extract any text that matches the pattern into context variables. """ - results = run('music.mpd.search', filter={ - 'artist': artist, - 'title': title, - }) + results = run( + 'music.mpd.search', + filter={ + 'artist': artist, + 'title': title, + }, + ) if results: run('music.mpd.play', results[0]['file']) diff --git a/platypush/builder/_base.py b/platypush/builder/_base.py index fe228fb2..73cf69c8 100644 --- a/platypush/builder/_base.py +++ b/platypush/builder/_base.py @@ -190,7 +190,7 @@ class BaseBuilder(ABC): if not opts.cfgfile: opts.cfgfile = os.path.join( str(pathlib.Path(inspect.getfile(Config)).parent), - 'config.auto.yaml', + 'config.yaml', ) logger.info('No configuration file specified. Using %s.', opts.cfgfile) diff --git a/platypush/config/config.auto.yaml b/platypush/config/config.auto.yaml deleted file mode 100644 index e9bbcd0c..00000000 --- a/platypush/config/config.auto.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Auto-generated configuration file. -# Do not edit manually - use the config.yaml file for manual modifications -# instead - -backend.http: - enabled: True diff --git a/platypush/config/config.yaml b/platypush/config/config.yaml index 1e36005f..7f31c3cd 100644 --- a/platypush/config/config.yaml +++ b/platypush/config/config.yaml @@ -1,2 +1,920 @@ -include: - - config.auto.yaml +################################################################################ +# Sample Platypush configuration file. +# +# Edit it and: +# - Copy it to /etc/platypush/config.yaml for system installation. +# - Copy it to ~/.config/platypush/config.yaml for user installation. +# - Start the application with `-c `. +# +# Since the configuration file also includes the custom integrations, you can +# create a Platypush custom installation, with all the extra dependencies +# required by the configured integrations, using the `platydock` or `platyvenv` +# commands and passing this file as an argument. These commands will build a +# Docker image or a Python virtual environment respectively, with all the +# required extra dependencies inferred from your configuration file. +# +# A `scripts` directory with an empty `__init__.py` script will also be created +# under the same directory as the configuration file. This directory can be +# used to add custom scripts containing procedures, hooks and crons if you want +# a full Python interface to define your logic rather than a YAML file. +# +# Please refer to the `scripts` directory provided under this file's directory +# for some examples that use the Python API. +################################################################################ + +### ------------------ +### Include directives +### ------------------ + +# # You can split your configuration over multiple files and use the include +# # directive to import other files into your configuration. +# +# # Files referenced via relative paths will be searched in the directory of +# # the configuration file that references them. Symbolic links are also +# # supported. +# +# include: +# - logging.yaml +# - media.yaml +# - sensors.yaml + +### ----------------- +### Working directory +### ----------------- + +# # Working directory of the application. This is where the main database will be +# # stored by default (if the default SQLite configuration is used), and it's +# # where the integrations will store their state. +# +# # Note that the working directory can also be specified at runtime using the +# # -w/--workdir option. +# # +# # If not specified, then one of the following will be used: +# # +# # - $XDG_DATA_HOME/platypush if the XDG_DATA_HOME environment variable is set. +# # - $HOME/.local/share/platypush otherwise. +# +# workdir: ~/.local/share/platypush + +### ---------------------- +### Database configuration +### ---------------------- + +# # By default Platypush will use a SQLite database named `main.db` under the +# # `workdir`. You can specify any other engine string here - the application has +# # been tested against SQLite, Postgres and MariaDB/MySQL >= 8. +# # +# # NOTE: If you want to use a DBMS other than SQLite, then you will also need to +# # ensure that a compatible Python driver is installed on the system where +# # Platypush is running. For example, Postgres will require the Python pg8000, +# # psycopg or another compatible driver. +# +# main.db: +# engine: sqlite:///home/user/.local/share/platypush/main.db +# # OR, if you want to use e.g. Postgres with the pg8000 driver: +# engine: postgresql+pg8000://dbuser:dbpass@dbhost/dbname + +### --------------------- +### Logging configuration +### --------------------- + +# # Platypush logs on stdout by default. You can use the logging section to +# # specify an alternative file or change the logging level. +# +# # Note that a custom logging directory can also be specified at runtime using +# # the -l/--logsdir option. +# +# logging: +# filename: ~/.local/log/platypush/platypush.log +# level: INFO + +### ----------------------- +### device_id configuration +### ----------------------- + +# # 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. +# +# # Note that a custom device ID can also be specified at runtime using the +# # -d/--device-id option. +# +# device_id: my_device + +### ------------------- +### Redis configuration +### ------------------- + +# # Platypush needs a Redis instance for inter-process communication. +# # +# # By default, the application will try and connect to a Redis server listening +# # on localhost:6379. +# # +# # Platypush can also start the service on the fly if instructed to do so +# # through the `--start-redis` option. You can also specify a custom port +# # through the `--redis-port` option. +# # +# # If you are running Platypush in a Docker image built through Platydock, then +# # `--start-redis` is the default behaviour and you won't need any extra +# # documentation here. +# +# redis: +# host: localhost +# port: 6379 +# username: user +# password: secret + +### ------------------------ +### Web server configuration +### ------------------------ + +# Platypush comes with a versatile Web server that is used to: +# +# - Serve the main UI and the UIs for the plugins that provide one. +# - Serve custom user-configured dashboards. +# - Expose the `/execute` RPC endpoint to send synchronous requests. +# - Expose the `/ws/events` and `/ws/requests` Websocket paths, which can be +# respectively by other clients to subscribe to the application's events or +# send asynchronous requests. +# - Stream media files provided by other plugins, as well as camera and audio +# feeds. +# - Serve custom directories of static files that can be accessed by other +# clients. +# - Provide a versatile API for hooks - the user can easily create custom HTTP +# hooks by creating a hook with their custom logic that reacts when a +# `platypush.message.event.http.hook.WebhookEvent` is received. The `hook` +# parameter of the event specifies which URL will be served by the hook. +# +# The Web server is enabled by default, but you can disable it simply by +# commenting/removing the `backend.http` section. The default listen port is +# 8008. +# +# After starting the application, you can access the UI at +# http://localhost:8008, set up your username and password, and also create an +# access or session token from the configuration panel. +# +# This token can be used to authenticate calls to the available APIs. +# For example, to turn on the lights using the /execute endpoint: +# +# curl -XPOST -H "Authorization: Bearer $TOKEN" \ +# -H "Content-Type: application/json" \ +# -d ' +# { +# "type": "request", +# "action": "light.hue.on", +# "args": { +# "lights": ["Bedroom"] +# } +# }' http://localhost:8008/execute +# +# If you want to serve the Web server behind a reverse proxy, you can copy the +# reference configuration available at +# https://git.platypush.tech/platypush/platypush/src/branch/master/examples/nginx/nginx.sample.conf + +backend.http: + # # Bind address (default: 0.0.0.0) + # bind_address: 0.0.0.0 + # # Listen port (default: 8008) + port: 8008 + + # # resource_dirs can be used to specify directories on the host system that + # # you want to expose through the Web server. For example, you may want to + # # expose directories that contain photos or images if you want to make a + # # carousel dashboard, or a directory containing some files that you want to + # # share with someone (or other systems) using a simple Web server. + # # + # # In the following example, we're exposing a directory with photos on an + # # external hard drive other the `/photos` URL. An image like e.g. + # # `/mnt/hd/photos/IMG_1234.jpg` will be served over e.g. + # # `http://localhost:8008/photos/IMG_1234.jpg` in this case. + # resource_dirs: + # photos: /mnt/hd/photos + + # # Number of WSGI workers. Default: (#cpus * 2) + 1 + # num_workers: 4 + +### ----------------------------- +### Plugin configuration examples +### ----------------------------- + +### +# # The configuration of a plugin matches one-to-one the parameters required by +# # its constructor. +# # +# # Plugin classes are documented at https://docs.platypush.tech/en/latest/plugins.html +# # +# # For example, there is a `light.hue` plugin +# # (https://docs.platypush.tech/platypush/plugins/light.hue.html) whose +# # constructor takes the following parameters: `bridge`, `lights` (default +# # target lights for the commands), `groups` (default target groups for the +# # commands) and `poll_interval` (how often the plugin should poll for updates). +# # +# # This means that the `light.hue` plugin can be configured here as: +# +# light.hue: +# # IP address or hostname of the Hue bridge +# # NOTE: The first run will require you to register the application with +# # your bridge - that's usually done by pressing a physical button on your +# # bridge while the application is pairing. +# bridge: 192.168.1.3 +# # Groups that will be handled by default if nothing is specified on the request +# groups: +# - Living Room +# +# # How often we should poll for updates (default: 20 seconds) +# poll_interval: 20 +### + +### +# # Example configuration of music.mpd plugin, a plugin to interact with MPD and +# # Mopidy music server instances. 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 +### + +### +# # Plugins with empty configuration can also be explicitly enabled by specifying +# # `enabled: true` or `disabled: false`. An integration with no items will be +# # enabled with no configuration. +# +# clipboard: +### + +### +# # Example configuration of the MQTT plugin. This specifies a server that the +# # application will use by default (if not specified on the request body). +# +# mqtt: +# host: 192.168.1.2 +# port: 1883 +# username: user +# password: secret +### + +### +# # Enable the system plugin if you want your device to periodically report +# # system statistics (CPU load, disk usage, memory usage etc.) +# # +# # When new data is gathered, an `EntityUpdateEvent` with `plugin='system'` will +# # be triggered with the new data, and you can subscribe a hook to these events +# # to run your custom logic. +# +# system: +# # How often we should poll for new data +# poll_interval: 60 +### + +### +# # Example configuration for the calendar plugin. In this case, we have +# # registered a Google calendar that uses the `google.calendar` integration, and +# # a Facebook plugin and a NextCloud (WebDAV) plugin exposed over iCal format. +# # 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 +# - type: platypush.plugins.calendar.ical.CalendarIcalPlugin +# url: http://riemann/nextcloud/remote.php/dav/public-calendars/9JBWHR7iioM88Y4D?export +### + +### +# # Torrent plugin configuration, with the default directory that should be used +# # to store downloaded files. +# +# torrent: +# download_dir: ~/Downloads +### + +### +# # List of RSS/Atom subscriptions. These feeds will be monitored for changes and +# # a `platypush.message.event.rss.NewFeedEntryEvent` +# # (https://docs.platypush.tech/platypush/events/rss.html#platypush.message.event.rss.NewFeedEntryEvent) +# # will be triggered when one of these feeds has new entries - you can subscribe +# # the event to run your custom logic. +# +# rss: +# # How often we should check for updates (default: 5 minutes) +# poll_seconds: 300 +# # List of feeds to monitor +# subscriptions: +# - https://www.theguardian.com/rss/world +# - https://phys.org/rss-feed/ +# - https://news.ycombinator.com/rss +# - https://www.technologyreview.com/stories.rss +# - https://api.quantamagazine.org/feed/ +### + +### +# # Example configuration of a weather plugin +# +# weather.openweathermap: +# token: secret +# lat: lat +# long: long +### + +### +# # You can add IFTTT integrations to your routines quite easily. +# # +# # Register an API key for IFTTT, paste it here, and you can run an +# # `ifttt.trigger_event` action to fire an event on IFTTT. +# # +# # You can also create IFTTT routines that call your Platypush instance, by +# # using Web hooks (i.e. event hooks that subscribe to +# # `platypush.message.event.http.hook.WebhookEvent` events), provided that the +# # Web server is listening on a publicly accessible address. +# +# ifttt: +# ifttt_key: SECRET +### + +### +# # The `http.webpage` integration comes with the mercury-parser JavaScript library. +# # It allows you to "distill" the content of a Web page and export it in readable format (in simplified HTML, Markdown or PDF) through the +# +# http.webpage: +### + +### +# # Example configuration of the zigbee.mqtt integration. +# # This integration listens for the events pushed by zigbee2mqtt service to an +# # MQTT broker. It can forward those events to native Platypush events (see +# # https://docs.platypush.tech/platypush/events/zigbee.mqtt.html) that you can +# # build automation routines on. You can also use Platypush to control your +# # Zigbee devices, either through the Web interface or programmatically through +# # the available plugin actions. +# +# zigbee.mqtt: +# # Host of the MQTT broker +# host: riemann +# # Listen port of the MQTT broker +# port: 1883 +# # Base topic, as specified in `/data/configuration.yaml` +# base_topic: zigbee2mqtt +### + +### +# # Example configuration of the zwave.mqtt integration. +# # This integration listens for the events pushed by ZWaveJS service to an MQTT +# # broker. It can forward those events to native Platypush events (see +# # https://docs.platypush.tech/platypush/events/zwave.html) that you can build +# # automation routines on. +# # You can also use Platypush to control your Z-Wave devices, either through the +# # Web interface or programmatically through the available plugin actions. +# +# zwave.mqtt: +# # Host of the MQTT broker +# host: riemann +# # Listen port of the MQTT broker +# port: 1883 +# # Gateway name, usually configured in the ZWaveJS-UI through `Settings -> +# # MQTT -> Name` +# name: zwavejs2mqtt +# # The prefix of the published topics, usually configured in the ZWaveJS-UI +# # through `Settings -> MQTT -> Prefix`. +# topic_prefix: zwave +### + +### -------------------- +### Camera configuration +### -------------------- + +### +# # There are several providers for the camera integration - you can choose +# # between ffmpeg, gstreamer, PiCamera etc., and they all expose the same +# # interface/configuration options. +# # +# # It is advised to use the ffmpeg integration, as it's the one that provides +# # the highest degree of features and supported hardware. +# # +# # If the plugin is correctly configured, you can access your camera feed from +# # the Platypush Web panel, programmatically start/stop recording sessions, take +# # photos, get a feed stream URL etc. +# +# # The camera feed will be available at `/camera//video[.extension]`, +# # for example `/camera/ffmpeg/video.mjpeg` for MJPEG (usually faster), or +# # `camera/ffmpeg/video.mp4` for MP4. +# +# # You can also capture images by connecting to the +# # `/camera//photo[.extension]`, for example `/camera/ffmpeg/photo.jpg`. +# +# camera.ffmpeg: +# # Default video device to use +# device: /dev/video0 +# # Default resolution +# resolution: +# - 640 +# - 480 +# # The directory that will be used to store captured frames/images +# frames_dir: ~/Camera/Photos +# # Default image scaling factors (default: 1, no scaling) +# scale_x: 1.5 +# scale_y: 1.5 +# # Default rotation of the image, in degrees (default: 0, no rotation) +# rotate: 90 +# # Grayscale mode (default: False): +# grayscale: false +# # Default frames per second (default: 16) +# fps: 16 +# # Whether to flip the image along the horizontal axis (default: False) +# horizontal_flip: false +# # Whether to flip the image along the horizontal axis (default: False) +# vertical_flip: false +### + +### ----------------- +### Sound integration +### ----------------- + +### +# # The sound plugin allows you to stream from an audio source connected to the +# # machine, play audio files or synthetic audio waves or MIDI sounds. +# +# # After enabling the plugin, you can access the audio stream at +# # `/sound/stream[.extension]` (e.g. `/sound/stream.mp3`) if you want to get a +# # live recording of the captured sound from the configured audio +# # `input_device`. +# +# sound: +# enabled: true +### + +### ----------------------------------- +### Some examples of media integrations +### ----------------------------------- + +### +# # Example configuration for the media.vlc plugin. You can replace `vlc` with +# # `mpv`, `mplayer`, `omxplayer` or `gstreamer` if you want to use another +# # player - the supported configuration option are the same across all these +# # players. +# +# media.vlc: +# # Volume level, between 0 and 100 +# volume: 50 +# # Where to store downloaded files +# download_dir: ~/Downloads +# # Play videos in fullscreen by default +# fullscreen: True +# # If youtube-dl or any compatible application is installed, play requested +# # videos in this format by default. Default: `best`. +# youtube_format: 'mp4[height<=?480]' +# # Extra arguments to pass to the executable. --play-and-exit may be a good +# # idea with VLC, so the player terminates upon stop instead of lingering in +# # the background. +# args: +# - --play-and-exit +# # List of directories to search for media files. The media files in these +# # folders can be searched through the `media..search` command, or +# # through the Web interface. +# media_dirs: +# - /mnt/hd/media/movies +# - /mnt/hd/media/series +# - /mnt/hd/media/videos +# - ~/Downloads +### + +### +# # Example configuration for the 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 +### + +### +# # Example Kodi configuration. This makes it possible to control and query a +# # Kodi instance, from your automation hooks, from the Platypush APIs or from +# # the Platypush Web interface. It requires you to enable the JSON API service +# # from Kodi's settings. +# +# media.kodi: +# host: localhost +# http_port: 8080 +# username: kodi +# password: secret +### + +### +# # Example configuration for a Plex media server. This integration makes it +# # possible to navigate and search media items from your Plex library in the +# # media UI. +# +# media.plex: +# server: localhost +# username: plex +# password: secret +### + +### +# # Jellyfin media server configuration. +# +# media.jellyfin: +# server: https://media.example.com +# api_key: secret +### + +### --------------------- +### Sensors configuration +### --------------------- + +### +# # The serial plugin can be used to read sensor data from a device connected +# # over serial/USB interface. +# # +# # It can be used, for example, to connect to an Arduino or ESP device over +# # serial port, where the remote microcontroller periodically sends sensor data +# # over the serial interface. +# # +# # The data can be sent on the wire either as raw string-encoded numbers (one +# # per line), or (better) in JSON format. For example, you can program your +# # microcontroller to periodically send JSON strings like these when you get new +# # readings from your sensors: +# # +# # {"temperature": 25.0, "humidity": 20.0, "smoke": 0.01, "luminosity": 45} +# # +# # The JSON will be automatically unpacked by the application, and the relevant +# # `platypush.message.event.sensor.SensorDataChangeEvent` events will be +# # triggered when the data changes - you can subscribe to them in your custom +# # hooks. +# +# serial: +# # The path to the USB interface with e.g. an Arduino or ESP microcontroller +# # connected. +# # A way to get a deterministic path name on Linux, instead of +# # `/dev/ttyUSB`, can be the following: +# # +# # - Get the vendor and product ID of your device via e.g. `lsusb`. For +# # example, for an Arduino-compatible microcontroller: +# # +# # Bus 001 Device 008: ID 1a86:7523 QinHeng Electronics CH340 serial converter +# # +# # - In the case above, `1a86` is the vendor ID and `7523` is the product +# # ID. Create a new udev rule for it, so every time the device is +# # connected it will also be symlinked to e.g. `/dev/arduino`: +# # +# # echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="arduino"' | \ +# # sudo tee /etc/udev/rules.d/98-usb-serial.rules +# device: /dev/ttyUSB0 +# # How often the interface should be polled for updates, in seconds +# poll_interval: 1 +# # The tolerance argument can be used to tune when you want to be notified +# # of data changes through `SensorDataChangeEvent` events. In the case +# # below, if the microcontroller sends two consecutive temperature reads, +# # one for 22.0 and one for 22.2, then only one `SensorDataChangeEvent` will +# # be triggered (for the first read), since the absolute value of the +# # difference between the two events is less than the configured tolerance. +# # However, if the device sends two temperature reads, one for 22.0 and one +# # for 22.7, then two `SensorDataChangeEvent` events will be triggered. +# # The tolerance for all the metrics is set to a value close to zero by +# # default - i.e. any read, unless it's exactly the same as the previous +# # one, will trigger a new event. +# tolerance: +# temperature: 0.5 +# humidity: 0.75 +# luminosity: 5 +# +# # If a threshold is defined for a sensor, and the value of that sensor goes +# # below/above that temperature between two reads, then a +# # `SensorDataBelowThresholdEvent` or a `SensorDataAboveThresholdEvent` will +# # be triggered respectively. +# thresholds: +# temperature: 25.0 +### + +### +# # Alternatively to the serial plugin, you can also use the arduino plugin if +# # you want to specifically interface with Arduino. +# # +# # This plugin won't require you to write any logic for your microcontroller. +# # However, it requires your microcontroller to be flash with the Firmata +# # firmware, which allows programmatic external control. +# # +# # Note that the interface of this plugin is basically the same as the serial +# # plugin, and any other plugin that extends `SensorPlugin` in general. +# # Therefore, poll_interval, tolerance and thresholds are supported here too. +# +# arduino: +# board: /dev/ttyUSB0 +# # name -> PIN number mapping (similar for digital_pins). +# # It allows you to pick a common name for your PINs that will be used in +# # the forwarded events. +# analog_pins: +# temperature: 7 +# +# tolerance: +# temperature: 0.5 +# +# thresholds: +# temperature: 25.0 +### + +### +# # Another example: the LTR559 is a common sensor for proximity and luminosity +# # that can be wired to a Raspberry Pi or similar devices over SPI or I2C +# # interface. It exposes the same base interface as all other sensor plugins. +# +# sensor.ltr559: +# poll_interval: 1.0 +# tolerance: +# light: 7.0 +# proximity: 5.0 +# +# thresholds: +# proximity: 10.0 +### + +### -------------------------------- +### Some text-to-speech integrations +### -------------------------------- + +### +# # `tts` is the simplest TTS integration. It leverages the Google Translate open +# # "say" endpoint to render text as audio speech. +# +# tts: +# # The media plugin that should be used to play the audio response +# media_plugin: media.vlc +# # The default language of the voice +# language: en-gb +### + +### +# # `tts.google` leverages Google's official text-to-speech API to render audio +# # speech from text. +# # +# # Install its dependencies via 'pip install "platypush[google-tts]"'. +# # +# # Like all other Google integrations, it requires you to register an app on the +# # Google developers console, create an API key, and follow the instruction +# # logged on the next restart to give your app the required permissions to your +# # account. +# +# tts.google: +# # The media plugin that should be used to play the audio response +# media_plugin: media.vlc +# # The default language of the voice +# language: en-US +# # The gender of the voice (MALE or FEMALE) +# gender: FEMALE +# # The path to the JSON file containing your Google API credentials +# credentials_file: '~/.credentials/platypush/google/platypush-tts.json' +### + +### +# # This TTS integration leverages mimic3, an open-source TTS Web server +# # developed by Mycroft (RIP). +# # +# # Follow the instructions at +# # https://docs.platypush.tech/platypush/plugins/tts.mimic3.html to quickly +# # bootstrap a mimic3 server. +# +# tts.mimic3: +# # The base URL of the mimic3 server +# server_url: http://riemann:59125 +# # Path of the default voice that should be used +# voice: 'en_UK/apope_low' +# # The media plugin that should be used to play the audio response +# media_plugin: media.vlc +### + +## ---------- +## Procedures +## ---------- + +# Procedures are lists of actions that are executed sequentially. +# +# This section shows how to define procedures directly in your YAML +# configuration file(s). However, you can also put your procedures into Python +# scripts inside of the `/scripts` directory if you want access to +# a full-blown Python syntax. They will be automatically discovered at startup +# and available to the application. +# +# You can also access Python variables and evaluate Python expressions by using +# `${}` context 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 `${context["status"]}` or +# `${context["temperature"]}`, or simply `${status}` and `${temperature}`, +# respectively. +# +# You can also add statements like `- if ${temperature > 20.0}` or +# `- for ${temp in temperature_values}` in your procedures. +# +# Besides the `context` variables, the following special variables are also +# available to the `${}` constructs when running a procedure: +# +# - `output`: It contains the parsed output of the previous action. +# - `errors`: It contains the errors of the previous action +# - `event`: If the procedure is an event hook (or it 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 from the Platypush `execute` Web panel, or +# # programmatically by sending a JSON request to your Web server (or to the +# # `/ws/requests` Websocket route, or to the TCP backend) +# # +# # curl -XPOST \ +# # -H "Authorization: Bearer $YOUR_TOKEN" \ +# # -d '{"type": "request", "action": "procedure.at_home"}' +# # +# # A use-case can be the one where you have a Tasker automation running on your +# # Android device that detects when your phone enters or exits a certain area, +# # and sends the appropriate request to your Platypush server. +# +# procedure.at_home: +# # Set the db variable AT_HOME to 1. +# # Variables are flexible entities with a name and a value that will be +# # stored on the database and persisted across sessions. +# # You can access them in other procedures, scripts or hooks and run +# # custom logic on the basis of their value. +# - action: variable.set +# args: +# AT_HOME: 1 +# +# # Check the luminosity level from e.g. a connected LTR559 sensor. +# # It could also be a Bluetooth, Zigbee, Z-Wave, serial etc. sensor. +# - action: sensor.ltr559.get_measurement +# +# # If it's below a certain threshold, turn on the lights. +# # In this case, `light` is a parameter returned by the previous response, +# # so we can directly access it here through the `${}` context operator. +# # ${light} in this case is equivalent to ${context["light"]} or +# # ${output["light"]}. +# - if ${int(light or 0) < 110}: +# - action: light.hue.on +# +# # Say a welcome home message +# - action: tts.mimic3.say +# args: +# text: Welcome home +# +# # Start the music +# - action: music.mpd.play +### + +### +# # Procedure that will be execute when you walk outside your home. +# +# procedure.outside_home: +# # Unset the db variable AT_HOME +# - action: variable.unset +# args: +# name: AT_HOME +# +# # Stop the music +# - action: music.mpd.stop +# +# # Turn off the lights +# - action: light.hue.off +### + +### +# # Procedures can also take optional arguments. The example below shows a +# # generic procedure that broadcasts measurements from a sensor through an +# MQTT broker. +# +# # A listener on this topic can react to an `MQTTMessageEvent` and, for +# # example, store the event on a centralized storage. +# # +# # See the event hook section below for a sample hook that listens for messages +# # sent by other clients using this procedure. +# +# procedure.send_sensor_data(name, value): +# - action: mqtt.send_message +# args: +# topic: platypush/sensors +# host: mqtt-server +# port: 1883 +# msg: +# name: ${name} +# value: ${value} +# source: ${Config.get("device_id")} +### + +## ------------------- +## Event hook examples +## ------------------- + +# Event hooks are procedures that are run when a certain condition is met. +# +# Check the documentation of your configured backends and plugins to see which +# events they can trigger, and check https://docs.platypush.tech/events.html +# for the full list of available events with their schemas. +# +# Just like procedures, event hooks can be defined either using the YAML +# syntax, or in Python snippets in your `scripts` folder. +# +# A YAML event hook consists of two parts: an `if` field that specifies on +# which event the hook will be triggered (type and attribute values), and a +# `then` field that uses the same syntax as procedures to specify a list of +# actions to execute when the event is matched. + +### +# # This example is a hook that reacts when an `MQTTMessageEvent` is received on +# # a topic named `platypush/sensor` (see `send_sensor_data` example from the +# # procedures section). +# # +# # It will store the event on a centralized Postgres database. +# # +# # Note that, for this event to be triggered, the application must first +# # subscribe to the `platypush/sensor` topic - e.g. by adding `platypush/sensor` +# # to the active subscriptions in the `mqtt` configurations. +# +# event.hook.OnSensorDataReceived: +# if: +# type: platypush.message.event.mqtt.MQTTMessageEvent +# topic: platypush/sensor +# then: +# - action: db.insert +# args: +# engine: postgresql+pg8000://dbuser:dbpass@dbhost/dbname +# table: sensor_data +# records: +# - name: ${msg["name"]} +# value: ${msg["value"]} +# source: ${msg["source"]} +### + +### +# # 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 for `SpeechRecognizedEvent`, +# # 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 +### + +### +# # The WebhookEvent is a special type of event. It allows you to dynamically +# # register a Web hook that can be invoked by other clients, if the HTTP backend +# # is active. +# # +# # In this case, we are registering a hook under `/hook/test-hook` that accepts +# # POST requests, gets the body of the requests and logs it. +# # +# # NOTE: Since Web hooks are supposed to be called by external (and potentially +# # untrusted) parties, they aren't designed to use the standard authentication +# # mechanism used by all other routes. +# # +# # By default they don't have an authentication layer at all. You are however +# # advised to create your custom passphrase and checks the request's headers or +# # query string for it - preferably one passphrase per endpoint. +# +# event.hook.WebhookExample: +# if: +# type: platypush.message.event.http.hook.WebhookEvent +# hook: test-hook +# method: POST +# then: +# # Check the token/passphrase +# - if ${args.get('headers', {}).get('X-Token') == 'SECRET': +# - action: logger.info +# args: +# msg: ${data} +### + +### ------------- +### 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 +###