Updated README

This commit is contained in:
Fabio Manganiello 2023-05-09 02:54:02 +02:00
parent ab2425ebd0
commit 5415f0ccf3
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774

727
README.md
View file

@ -4,22 +4,16 @@ Platypush
[![Build Status](https://ci.platypush.tech/status.svg)](https://ci.platypush.tech/latest.log) [![Build Status](https://ci.platypush.tech/status.svg)](https://ci.platypush.tech/latest.log)
[![Documentation Status](https://ci.platypush.tech/docs/status.svg)](https://ci.platypush.tech/docs/latest.log) [![Documentation Status](https://ci.platypush.tech/docs/status.svg)](https://ci.platypush.tech/docs/latest.log)
[![pip version](https://img.shields.io/pypi/v/platypush.svg?style=flat)](https://pypi.python.org/pypi/platypush/) [![pip version](https://img.shields.io/pypi/v/platypush.svg?style=flat)](https://pypi.python.org/pypi/platypush/)
[![License](https://img.shields.io/github/license/BlackLight/platypush.svg)](https://git.platypush.tech/platypush/platypush/-/blob/master/LICENSE.txt) [![License](https://img.shields.io/github/license/BlackLight/platypush.svg)](https://git.platypush.tech/platypush/platypush/src/branch/master/LICENSE.txt)
[![Last Commit](https://img.shields.io/github/last-commit/BlackLight/platypush.svg)](https://git.platypush.tech/platypush/platypush/-/commits/master/) [![Last Commit](https://img.shields.io/github/last-commit/BlackLight/platypush.svg)](https://git.platypush.tech/platypush/platypush/commits/branch/master)
[![Join chat on Matrix](https://img.shields.io/matrix/:platypush?server_fqdn=matrix.platypush.tech)](https://matrix.to/#/#platypush:matrix.platypush.tech) [![Join chat on Matrix](https://img.shields.io/matrix/:platypush?server_fqdn=matrix.platypush.tech)](https://matrix.to/#/#platypush:matrix.platypush.tech)
[![Contributions](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://git.platypush.tech/platypush/platypush/-/blob/master/CONTRIBUTING.md) [![Contributions](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://git.platypush.tech/platypush/platypush/src/branch/master/CONTRIBUTING.md)
<!-- toc --> <!-- toc -->
- [Architecture](#architecture) + [Useful links](#useful-links)
* [Plugins](#plugins) - [Introduction](#introduction)
* [Actions](#actions) + [What it can do](#what-it-can-do)
* [Backends](#backends)
* [Events](#events)
* [Hooks](#hooks)
* [Procedures](#procedures)
* [Cronjobs](#cronjobs)
* [The web interface](#the-web-interface)
- [Installation](#installation) - [Installation](#installation)
* [System installation](#system-installation) * [System installation](#system-installation)
+ [Install through `pip`](#install-through-pip) + [Install through `pip`](#install-through-pip)
@ -31,17 +25,27 @@ Platypush
+ [Check the instructions reported in the documentation](#check-the-instructions-reported-in-the-documentation) + [Check the instructions reported in the documentation](#check-the-instructions-reported-in-the-documentation)
* [Virtual environment installation](#virtual-environment-installation) * [Virtual environment installation](#virtual-environment-installation)
* [Docker installation](#docker-installation) * [Docker installation](#docker-installation)
- [Architecture](#architecture)
* [Plugins](#plugins)
* [Actions](#actions)
* [Backends](#backends)
* [Events](#events)
* [Hooks](#hooks)
* [Procedures](#procedures)
* [Cronjobs](#cronjobs)
* [Entities](#entities)
* [The web interface](#the-web-interface)
- [Mobile app](#mobile-app) - [Mobile app](#mobile-app)
- [Tests](#tests) - [Tests](#tests)
- [Funding](#funding) - [Funding](#funding)
<!-- tocstop --> <!-- tocstop -->
#### Useful links
- Recommended read: [**Getting started with Platypush**](https://blog.platypush.tech/article/Ultimate-self-hosted-automation-with-Platypush). - Recommended read: [**Getting started with Platypush**](https://blog.platypush.tech/article/Ultimate-self-hosted-automation-with-Platypush).
- The [blog](https://blog.platypush.tech) is in general a good place to get - The [blog](https://blog.platypush.tech) is a good place to get more insights
more insights on what you can build with it and inspiration about possible and inspiration on what you can build.
usages.
- The [wiki](https://git.platypush.tech/platypush/platypush/wiki) also - The [wiki](https://git.platypush.tech/platypush/platypush/wiki) also
contains many resources on getting started. contains many resources on getting started.
@ -49,19 +53,19 @@ Platypush
- Extensive documentation for all the available integrations and messages [is - Extensive documentation for all the available integrations and messages [is
available](https://docs.platypush.tech/). available](https://docs.platypush.tech/).
- If you have issues/feature requests/enhancement ideas please [create an - If you have issues/feature requests/enhancements please [create an
issue](https://git.platypush.tech/platypush/platypush/-/issues). issue](https://git.platypush.tech/platypush/platypush/issues).
- A [Reddit channel](https://www.reddit.com/r/platypush) is also available for
more general questions.
- A [Matrix instance](https://matrix.to/#/#platypush:matrix.platypush.tech) is - A [Matrix instance](https://matrix.to/#/#platypush:matrix.platypush.tech) is
also available if you are looking for more interactive support. available if you are looking for interactive support.
--- - A [Reddit channel](https://www.reddit.com/r/platypush) is available for
general questions.
Platypush is a general-purpose extensible platform for automation and ## Introduction
integration across multiple services and devices.
Platypush is a general-purpose extensible platform for automation across
multiple services and devices.
It enables users to create their own self-hosted pieces of automation based on It enables users to create their own self-hosted pieces of automation based on
events (*if this happens then do that*) events (*if this happens then do that*)
@ -70,16 +74,15 @@ everything you need to visualize and control under one roof.
It takes some concepts from [IFTTT](https://ifttt.com), It takes some concepts from [IFTTT](https://ifttt.com),
[Tasker](https://tasker.joaoapps.com/), [Microsoft [Tasker](https://tasker.joaoapps.com/), [Microsoft
Flow](https://flow.microsoft.com), [PushBullet](https://pushbullet.com) and Flow](https://flow.microsoft.com) and [Home
[Home Assistant](https://www.home-assistant.io/) to provide an environment Assistant](https://www.home-assistant.io/) to provide an environment where the
where the user can easily connect things together. user can easily connect things together.
Its ideal home is a single-board computer like a RaspberryPi that you can It's built with compatibility and flexibility in mind, and it can easily run on
configure to orchestrate any home automation and cloud automation in your own any device that can run a Python interpreter - from a Raspberry Pi zero, to an
living room or garage, but it can easily run on any device that can run a old smartphone, to a beefy server.
Python interpreter, and the bar for the hardware requirements is very low as
well - I use it to run pieces of automation on devices as powerful as a #### What it can do
RaspberryPi Zero or an old Nokia N900 with Linux.
You can use Platypush to do things like: You can use Platypush to do things like:
@ -110,323 +113,7 @@ You can use Platypush to do things like:
- [Create a custom single hub for Zigbee and Z-Wave smart devices](https://blog.platypush.tech/article/Transform-a-RaspberryPi-into-a-universal-Zigbee-and-Z-Wave-bridge) - [Create a custom single hub for Zigbee and Z-Wave smart devices](https://blog.platypush.tech/article/Transform-a-RaspberryPi-into-a-universal-Zigbee-and-Z-Wave-bridge)
- Build your own web dashboard with calendar, weather, news and music controls - Build your own web dashboard with calendar, weather, news and music controls
(basically, anything that has a Platypush web widget) (basically, anything that has a Platypush web widget)
- ...and much more (basically, anything that comes with a [Platypush plugin](https://docs.platypush.tech/en/latest/plugins.html)) - ...and much more (basically, anything that comes with a [Platypush plugin](https://docs.platypush.tech))
## Architecture
The architecture of Platypush consists of a few simple pieces, orchestrated by
a configuration file stored by default under
[`~/.config/platypush/config.yaml`](https://git.platypush.tech/platypush/platypush/-/blob/master/examples/conf/config.yaml):
### Plugins
[Full list](https://docs.platypush.tech/en/latest/plugins.html)
Plugins are integrations that do things - like [modify
files](https://docs.platypush.tech/en/latest/platypush/plugins/file.html),
[train and evaluate machine learning
models](https://docs.platypush.tech/en/latest/platypush/plugins/tensorflow.html),
[control
cameras](https://docs.platypush.tech/en/latest/platypush/plugins/camera.pi.html),
[read
sensors](https://docs.platypush.tech/en/latest/platypush/plugins/gpio.sensor.dht.html),
[parse a web
page](https://docs.platypush.tech/en/latest/platypush/plugins/http.webpage.html),
[control
lights](https://docs.platypush.tech/en/latest/platypush/plugins/light.hue.html),
[send
emails](https://docs.platypush.tech/en/latest/platypush/plugins/mail.smtp.html),
[control
Chromecasts](https://docs.platypush.tech/en/latest/platypush/plugins/media.chromecast.html),
[run voice
queries](https://docs.platypush.tech/en/latest/platypush/plugins/assistant.google.html),
[handle torrent
transfers](https://docs.platypush.tech/en/latest/platypush/plugins/torrent.html)
or control
[Zigbee](https://docs.platypush.tech/en/latest/platypush/plugins/zigbee.mqtt.html)
or [Z-Wave](https://docs.platypush.tech/en/latest/platypush/plugins/zwave.html)
devices.
The configuration of a plugin matches one-on-one that of its documented class
constructor, so it's very straightforward to write a configuration for a plugin
by reading its documentation:
```yaml
light.hue:
# Groups that will be controlled by default
groups:
- Living Room
- Hall
```
### Actions
Plugins expose *actions*, that match one-on-one the plugin class methods
denoted by `@action`, so it's very straightforward to invoke plugin actions by
just reading the plugin documentation. They can be invoked directly from your
own scripts or they can be sent to the platform through any supported channel
as simple JSON messages:
```json
{
"type": "request",
"action": "light.hue.on",
"args": {
"lights": ["Entrance Bulb"]
}
}
```
### Backends
[Full list](https://docs.platypush.tech/en/latest/backends.html)
They are background services that either listen for messages on channels (like
an [HTTP
backend](https://docs.platypush.tech/en/latest/platypush/backend/http.html), an
[MQTT
instance](https://docs.platypush.tech/en/latest/platypush/backend/mqtt.html), a
[Kafka
instance](https://docs.platypush.tech/en/latest/platypush/backend/kafka.html),
[Pushbullet](https://docs.platypush.tech/en/latest/platypush/backend/pushbullet.html)
etc.) or monitor a device or a service for events (like a
[sensor](https://docs.platypush.tech/en/latest/platypush/backend/sensor.html),
a custom [voice
assistant](https://docs.platypush.tech/en/latest/platypush/backend/assistant.google.html),
a bridge running on a
[Zigbee](https://docs.platypush.tech/en/latest/platypush/backend/zigbee.mqtt.html)
or
[Z-Wave](https://docs.platypush.tech/en/latest/platypush/backend/zwave.html),
an [NFC card
reader](https://docs.platypush.tech/en/latest/platypush/backend/nfc.html), a
[MIDI
device](https://docs.platypush.tech/en/latest/platypush/backend/midi.html), a
[Telegram
channel](https://docs.platypush.tech/en/latest/platypush/backend/chat.telegram.html),
a [Bluetooth
scanner](https://docs.platypush.tech/en/latest/platypush/backend/bluetooth.scanner.ble.html)
etc.).
If a backend supports the execution of requests (e.g. HTTP, MQTT, Kafka,
Websocket and TCP) then you can send requests to these services in JSON format.
For example, in the case of the HTTP backend:
```shell
# Get a token
curl -XPOST -H 'Content-Type: application/json' -d '
{
"username": "$YOUR_USER",
"password": "$YOUR_PASSWORD"
}' http://host:8008/auth
# Execute a request
curl -XPOST -H 'Content-Type: application/json' \
-H "Authorization: Bearer $YOUR_TOKEN" -d '
{
"type": "request",
"action": "tts.say",
"args": {
"text": "This is a test"
}
}' http://host:8008/execute
```
### Events
[Full list](https://docs.platypush.tech/en/latest/events.html)
When a certain event occurs (e.g. a JSON request is received, or a [Bluetooth
device is
connected](https://docs.platypush.tech/en/latest/platypush/events/bluetooth.html#platypush.message.event.bluetooth.BluetoothDeviceConnectedEvent),
or a [Flic button is
pressed](https://docs.platypush.tech/en/latest/platypush/events/button.flic.html#platypush.message.event.button.flic.FlicButtonEvent),
or some [speech is detected on the voice assistant
service](https://docs.platypush.tech/en/latest/platypush/events/assistant.html#platypush.message.event.assistant.SpeechRecognizedEvent),
or an [RSS feed has new
items](https://docs.platypush.tech/en/latest/platypush/events/http.rss.html#platypush.message.event.http.rss.NewFeedEvent),
or a [new email is
received](https://docs.platypush.tech/en/latest/platypush/events/mail.html#platypush.message.event.mail.MailReceivedEvent),
or a [new track is
played](https://docs.platypush.tech/en/latest/platypush/events/music.html#platypush.message.event.music.NewPlayingTrackEvent),
or an [NFC tag is
detected](https://docs.platypush.tech/en/latest/platypush/events/nfc.html#platypush.message.event.nfc.NFCTagDetectedEvent),
or [new sensor data is
available](https://docs.platypush.tech/en/latest/platypush/events/sensor.html#platypush.message.event.sensor.SensorDataChangeEvent),
or [a value of a Zigbee device
changes](https://docs.platypush.tech/en/latest/platypush/events/zigbee.mqtt.html#platypush.message.event.zigbee.mqtt.ZigbeeMqttDevicePropertySetEvent),
etc.), the associated backend will trigger an
[event](https://docs.platypush.tech/en/latest/events.html).
### Hooks
Event hooks are custom pieces of logic that will be run when a certain event is
triggered. Hooks are the glue that connects events to actions, exposing a
paradigm similar to IFTTT (_if a certain event happens then run these
actions_). They can declared as:
- Sections of the [`config.yaml`](https://git.platypush.tech/platypush/platypush/-/blob/master/examples/conf/config.yaml).
Example:
```yaml
event.hook.SearchSongVoiceCommand:
if:
type: platypush.message.event.assistant.SpeechRecognizedEvent
phrase: "play ${title} by ${artist}"
then:
- action: music.mpd.clear
- action: music.mpd.search
args:
filter:
artist: ${artist}
title: ${title}
- if ${len(output)}:
- action: music.mpd.play
args:
resource: ${output[0]['file']}
```
- Stand-alone Python scripts stored under `~/.config/platypush/scripts` and
will be dynamically imported at start time.
[Example](https://git.platypush.tech/platypush/platypush/-/blob/master/examples/conf/hook.py):
```python
from platypush.event.hook import hook
from platypush.utils import run
from platypush.message.event.assistant import SpeechRecognizedEvent
@hook(SpeechRecognizedEvent, phrase='play ${title} by ${artist}')
def on_music_play_command(event, title=None, artist=None, **context):
results = run('music.mpd.search', filter={
'artist': artist,
'title': title,
})
if results:
run('music.mpd.play', results[0]['file'])
```
### Procedures
Procedures are pieces of custom logic that can be executed as atomic actions
using `procedure.<name>` as an action name.
They can be defined either in the `config.yaml` or as Python scripts stored
under `~/.config/platypush/scripts` - provided that the procedure is also
imported in `~/.config/platypush/scripts/__init__.py` so it can be discovered
by the service.
YAML example for a procedure that can be executed when we arrive home and turns
on the lights if the luminosity is lower that a certain thresholds, says a
welcome home message using the TTS engine and starts playing the music:
```yaml
procedure.at_home:
# Get luminosity data from a sensor - e.g. LTR559
- action: gpio.sensor.ltr559.get_data
# If it's lower than a certain threshold, turn on the lights
- if ${int(light or 0) < 110}:
- action: light.hue.on
# Say a welcome home message
- action: tts.google.say
args:
text: Welcome home
# Play the music
- action: music.mpd.play
```
Python example:
```python
# Content of ~/.config/platypush/scripts/home.py
from platypush.procedure import procedure
from platypush.utils import run
@procedure
def at_home(**context):
sensor_data = run('gpio.sensor.ltr559.get_data')
if sensor_data['light'] < 110:
run('light.hue.on')
run('tts.google.say', text='Welcome home')
run('music.mpd.play')
```
In either case, you can easily trigger the at-home procedure by sending an
action request message to a backend - for example, over the HTTP backend:
```shell
curl -XPOST -H 'Content-Type: application/json' \
-H "Authorization: Bearer $YOUR_TOKEN" -d '
{
"type": "request",
"action": "procedure.at_home"
}' http://host:8008/execute
```
### Cronjobs
Cronjobs are pieces of logic that will be run at regular intervals, expressed
in crontab-compatible syntax. They can be defined either in the `config.yaml`
or as Python scripts stored under `~/.config/platypush/scripts` as functions
labelled by the `@cron` decorator.
Note that seconds are also supported (unlike the standard crontab definition),
but, for back-compatibility with the standard crontab format, they are at the
end of the cron expression, so the expression is actually in the format
`<minute> <hour> <day_of_month> <month> <day_of_week> <second>`.
YAML example for a cronjob that is executed every 30 seconds and checks if a
Bluetooth device is nearby:
```yaml
cron.check_bt_device:
cron_expression: '* * * * * */30'
actions:
- action: bluetooth.lookup_name
args:
addr: XX:XX:XX:XX:XX:XX
- if ${name}:
- action: procedure.on_device_on
- else:
- action: procedure.on_device_off
```
Python example:
```python
# Content of ~/.config/platypush/scripts/bt_cron.py
from platypush.cron import cron
from platypush.utils import run
@cron('* * * * * */30')
def check_bt_device(**context):
name = run('bluetooth.lookup_name').get('name')
if name:
# on_device_on logic here
else:
# on_device_off logic here
```
### The web interface
If
[`backend.http`](https://docs.platypush.tech/en/latest/platypush/backend/http.html)
is enabled then a web interface will be provided by default on
`http://host:8008/`. Besides using the `/execute` endpoint for running
requests, the built-in web server also provides a full-featured interface that
groups together the controls for most of the plugins - e.g. sensors, switches,
music controls and search, media library and torrent management, lights,
Zigbee/Z-Wave devices and so on. The UI is responsive and mobile-friendly.
The web service also provides means for the user to create [custom
dashboards](https://git.platypush.tech/platypush/platypush/-/blob/master/examples/conf/dashboard.xml)
that can be used to show information from multiple sources on a large screen.
## Installation ## Installation
@ -435,10 +122,10 @@ that can be used to show information from multiple sources on a large screen.
Platypush uses Redis to deliver and store requests and temporary messages: Platypush uses Redis to deliver and store requests and temporary messages:
```yaml ```yaml
# Example for Debian-based distributions # Example for Debian-based distributions
[sudo] apt-get install redis-server [sudo] apt-get install redis-server
# Enable and start the service # Enable and start the service
[sudo] systemctl enable redis [sudo] systemctl enable redis
[sudo] systemctl start redis [sudo] systemctl start redis
``` ```
@ -475,7 +162,7 @@ or tags.
git clone https://git.platypush.tech/platypush/platypush.git git clone https://git.platypush.tech/platypush/platypush.git
cd platypush cd platypush
[sudo] pip install . [sudo] pip install .
# Or # Or
[sudo] python3 setup.py install [sudo] python3 setup.py install
``` ```
@ -489,7 +176,7 @@ ways to check the dependencies required by an extension:
All the extensions that require extra dependencies are listed in the All the extensions that require extra dependencies are listed in the
[`extras_require` section under [`extras_require` section under
`setup.py`](https://git.platypush.tech/platypush/platypush/-/blob/master/setup.py#L72). `setup.py`](https://git.platypush.tech/platypush/platypush/src/branch/master/setup.py#L84).
#### Install via `manifest.yaml` #### Install via `manifest.yaml`
@ -532,7 +219,7 @@ platypush
It's advised to run it as a systemd service though - simply copy the provided It's advised to run it as a systemd service though - simply copy the provided
[`.service` [`.service`
file](https://git.platypush.tech/platypush/platypush/-/blob/master/examples/systemd/platypush.service) file](https://git.platypush.tech/platypush/platypush/src/branch/master/examples/systemd/platypush.service)
to `~/.config/systemd/user`, check if the path of `platypush` matches the path to `~/.config/systemd/user`, check if the path of `platypush` matches the path
where it's installed on your system, and start the service via `systemctl`: where it's installed on your system, and start the service via `systemctl`:
@ -613,6 +300,336 @@ directory in the same folder as the `config.yaml`.
[Wiki instructions](https://git.platypush.tech/platypush/platypush/wiki/Run-platypush-in-a-container) [Wiki instructions](https://git.platypush.tech/platypush/platypush/wiki/Run-platypush-in-a-container)
## Architecture
The architecture of Platypush consists of a few simple pieces, orchestrated by
a configuration file stored by default under
[`~/.config/platypush/config.yaml`](https://git.platypush.tech/platypush/platypush/src/branch/master/examples/conf/config.yaml):
### Plugins
[Full list](https://docs.platypush.tech/en/latest/plugins.html)
Plugins are integrations that do things - like [modify
files](https://docs.platypush.tech/en/latest/platypush/plugins/file.html),
[train and evaluate machine learning
models](https://docs.platypush.tech/en/latest/platypush/plugins/tensorflow.html),
[control
cameras](https://docs.platypush.tech/en/latest/platypush/plugins/camera.pi.html),
[read
sensors](https://docs.platypush.tech/en/latest/platypush/plugins/gpio.sensor.dht.html),
[parse a web
page](https://docs.platypush.tech/en/latest/platypush/plugins/http.webpage.html),
[control
lights](https://docs.platypush.tech/en/latest/platypush/plugins/light.hue.html),
[send
emails](https://docs.platypush.tech/en/latest/platypush/plugins/mail.smtp.html),
[control
Chromecasts](https://docs.platypush.tech/en/latest/platypush/plugins/media.chromecast.html),
[run voice
queries](https://docs.platypush.tech/en/latest/platypush/plugins/assistant.google.html),
[handle torrent
transfers](https://docs.platypush.tech/en/latest/platypush/plugins/torrent.html)
or control
[Zigbee](https://docs.platypush.tech/en/latest/platypush/plugins/zigbee.mqtt.html)
or [Z-Wave](https://docs.platypush.tech/en/latest/platypush/plugins/zwave.html)
devices.
The configuration of a plugin matches one-on-one that of its documented class
constructor, so it's very straightforward to write a configuration for a plugin
by reading its documentation:
```yaml
light.hue:
# Groups that will be controlled by default
groups:
- Living Room
- Hall
```
### Actions
Plugins expose *actions*, that match one-on-one the plugin class methods
denoted by `@action`, so it's very straightforward to invoke plugin actions by
just reading the plugin documentation. They can be invoked directly from your
own scripts or they can be sent to the platform through any supported channel
as simple JSON messages:
```json
{
"type": "request",
"action": "light.hue.on",
"args": {
"lights": ["Entrance Bulb"]
}
}
```
### Backends
[Full list](https://docs.platypush.tech/en/latest/backends.html)
They are background services that listen for messages on channels (like
an [HTTP
backend](https://docs.platypush.tech/en/latest/platypush/backend/http.html), an
[MQTT
instance](https://docs.platypush.tech/en/latest/platypush/backend/mqtt.html), a
[Kafka
instance](https://docs.platypush.tech/en/latest/platypush/backend/kafka.html),
[Pushbullet](https://docs.platypush.tech/en/latest/platypush/backend/pushbullet.html)
etc.).
If a backend supports the execution of requests (e.g. HTTP, MQTT, Kafka,
Websocket and TCP) then you can send requests to these services in JSON format.
For example, in the case of the HTTP backend:
```shell
# Get a token
curl -XPOST -H 'Content-Type: application/json' -d '
{
"username": "$YOUR_USER",
"password": "$YOUR_PASSWORD"
}' http://host:8008/auth
# Execute a request
curl -XPOST -H 'Content-Type: application/json' \
-H "Authorization: Bearer $YOUR_TOKEN" -d '
{
"type": "request",
"action": "tts.say",
"args": {
"text": "This is a test"
}
}' http://host:8008/execute
```
### Events
[Full list](https://docs.platypush.tech/en/latest/events.html)
When a certain event occurs (e.g. a JSON request is received, or a [Bluetooth
device is
connected](https://docs.platypush.tech/en/latest/platypush/events/bluetooth.html#platypush.message.event.bluetooth.BluetoothDeviceConnectedEvent),
or a [Flic button is
pressed](https://docs.platypush.tech/en/latest/platypush/events/button.flic.html#platypush.message.event.button.flic.FlicButtonEvent),
or some [speech is detected on the voice assistant
service](https://docs.platypush.tech/en/latest/platypush/events/assistant.html#platypush.message.event.assistant.SpeechRecognizedEvent),
or an [RSS feed has new
items](https://docs.platypush.tech/en/latest/platypush/events/http.rss.html#platypush.message.event.http.rss.NewFeedEvent),
or a [new email is
received](https://docs.platypush.tech/en/latest/platypush/events/mail.html#platypush.message.event.mail.MailReceivedEvent),
or a [new track is
played](https://docs.platypush.tech/en/latest/platypush/events/music.html#platypush.message.event.music.NewPlayingTrackEvent),
or an [NFC tag is
detected](https://docs.platypush.tech/en/latest/platypush/events/nfc.html#platypush.message.event.nfc.NFCTagDetectedEvent),
or [new sensor data is
available](https://docs.platypush.tech/en/latest/platypush/events/sensor.html#platypush.message.event.sensor.SensorDataChangeEvent),
or [a value of a Zigbee device
changes](https://docs.platypush.tech/en/latest/platypush/events/zigbee.mqtt.html#platypush.message.event.zigbee.mqtt.ZigbeeMqttDevicePropertySetEvent),
etc.), the associated backend will trigger an
[event](https://docs.platypush.tech/en/latest/events.html).
### Hooks
Event hooks are custom pieces of logic that will be run when a certain event is
triggered. Hooks are the glue that connects events to actions, exposing a
paradigm similar to IFTTT (_if a certain event happens then run these
actions_). They can declared as:
- Sections of the [`config.yaml`](https://git.platypush.tech/platypush/platypush/src/branch/master/examples/conf/config.yaml).
Example:
```yaml
event.hook.SearchSongVoiceCommand:
if:
type: platypush.message.event.assistant.SpeechRecognizedEvent
phrase: "play ${title} by ${artist}"
then:
- action: music.mpd.clear
- action: music.mpd.search
args:
filter:
artist: ${artist}
title: ${title}
- if ${len(output)}:
- action: music.mpd.play
args:
resource: ${output[0]['file']}
```
- Stand-alone Python scripts stored under `~/.config/platypush/scripts` and
will be dynamically imported at start time.
[Example](https://git.platypush.tech/platypush/platypush/src/branch/master/examples/conf/hook.py):
```python
from platypush.event.hook import hook
from platypush.utils import run
from platypush.message.event.assistant import SpeechRecognizedEvent
@hook(SpeechRecognizedEvent, phrase='play ${title} by ${artist}')
def on_music_play_command(event, title=None, artist=None, **context):
results = run('music.mpd.search', filter={
'artist': artist,
'title': title,
})
if results:
run('music.mpd.play', results[0]['file'])
```
### Procedures
Procedures are pieces of custom logic that can be executed as atomic actions
using `procedure.<name>` as an action name.
They can be defined either in the `config.yaml` or as Python scripts stored
under `~/.config/platypush/scripts` - provided that the procedure is also
imported in `~/.config/platypush/scripts/__init__.py` so it can be discovered
by the service.
YAML example for a procedure that can be executed when we arrive home and turns
on the lights if the luminosity is lower that a certain thresholds, says a
welcome home message using the TTS engine and starts playing the music:
```yaml
procedure.at_home:
# Get luminosity data from a sensor - e.g. LTR559
- action: gpio.sensor.ltr559.get_data
# If it's lower than a certain threshold, turn on the lights
- if ${int(light or 0) < 110}:
- action: light.hue.on
# Say a welcome home message
- action: tts.google.say
args:
text: Welcome home
# Play the music
- action: music.mpd.play
```
Python example:
```python
# Content of ~/.config/platypush/scripts/home.py
from platypush.procedure import procedure
from platypush.utils import run
@procedure
def at_home(**context):
sensor_data = run('gpio.sensor.ltr559.get_data')
if sensor_data['light'] < 110:
run('light.hue.on')
run('tts.google.say', text='Welcome home')
run('music.mpd.play')
```
In either case, you can easily trigger the at-home procedure by sending an
action request message to a backend - for example, over the HTTP backend:
```shell
curl -XPOST -H 'Content-Type: application/json' \
-H "Authorization: Bearer $YOUR_TOKEN" -d '
{
"type": "request",
"action": "procedure.at_home"
}' http://host:8008/execute
```
### Cronjobs
Cronjobs are pieces of logic that will be run at regular intervals, expressed
in crontab-compatible syntax. They can be defined either in the `config.yaml`
or as Python scripts stored under `~/.config/platypush/scripts` as functions
labelled by the `@cron` decorator.
Note that seconds are also supported (unlike the standard crontab definition),
but, for back-compatibility with the standard crontab format, they are at the
end of the cron expression, so the expression is actually in the format
`<minute> <hour> <day_of_month> <month> <day_of_week> <second>`.
YAML example for a cronjob that is executed every 30 seconds and checks if a
Bluetooth device is nearby:
```yaml
cron.check_bt_device:
cron_expression: '* * * * * */30'
actions:
- action: bluetooth.lookup_name
args:
addr: XX:XX:XX:XX:XX:XX
- if ${name}:
- action: procedure.on_device_on
- else:
- action: procedure.on_device_off
```
Python example:
```python
# Content of ~/.config/platypush/scripts/bt_cron.py
from platypush.cron import cron
from platypush.utils import run
@cron('* * * * * */30')
def check_bt_device(**context):
name = run('bluetooth.lookup_name').get('name')
if name:
# on_device_on logic here
else:
# on_device_off logic here
```
### Entities
Entities are a fundamental building block of Platypush. Most of the
integrations will store their state or connected devices in the form of
entities - e.g. the sensors detected by the Z-Wave/Zigbee/Bluetooth
integration, or the lights connected to a Hue bridge, or your cloud nodes, or
your custom Arduino/ESP machinery, and so on.
Entities provide a consistent interface to interact with your integrations
regardless of their type and the plugin that handles them. For instance, all
temperature sensors will expose the same interface, regardless if they are
Bluetooth or Zigbee sensors, and all the media plugins will expose the same
interface, regardless if they manage Chromecasts, Kodi, Plex, Jellyfin or a
local VLC player.
Once you enable the HTTP backend and a few integrations that export entities
and register a user, you can query the detected entities via:
```shell
curl -XPOST -H 'Content-Type: application/json' \
-H "Authorization: Bearer $YOUR_TOKEN" \
-d '{"type":"request", "action":"entities.get"}' \
http://localhost:8008/execute
```
All the entities expose the same interface and can be manipulated through the
same API. Also, when an entity is updated it always emits an
[`EntityUpdateEvent`](https://docs.platypush.tech/platypush/events/entities.html#platypush.message.event.entities.EntityUpdateEvent),
so you can easily create hooks that react to these events and act on multiple
types of entities.
### The web interface
If
[`backend.http`](https://docs.platypush.tech/en/latest/platypush/backend/http.html)
is enabled then a web interface will be provided by default on
`http://host:8008/`. Besides using the `/execute` endpoint for running
requests, the built-in web server also provides a full-featured interface that
groups together the controls for most of the plugins - e.g. sensors, switches,
music controls and search, media library and torrent management, lights,
Zigbee/Z-Wave devices and so on. The UI is responsive and mobile-friendly.
The web service also provides means for the user to create [custom
dashboards](https://git.platypush.tech/platypush/platypush/src/branch/master/examples/conf/dashboard.xml)
that can be used to show information from multiple sources on a large screen.
## Mobile app ## Mobile app
An [official Android An [official Android