Examples¶
Compiles a set of example configs to inspire you what you can achieve by using pnp.
Backup to dropbox¶
# Every sunday at 1am a backup of the specified directory is created
# and stored at the dropbox service.
tasks:
- name: cron_backup
pull:
plugin: pnp.plugins.pull.simple.Cron
args:
expressions:
- "0 1 * * SUN /tmp"
push:
plugin: pnp.plugins.push.fs.Zipper
deps:
- plugin: pnp.plugins.push.storage.Dropbox
args:
api_key: !env DROPBOX_API_KEY
create_shared_link: false
selector:
data: "lambda payload: payload"
target_file_name: "lambda payload: '{}_{}'.format(str(now()), basename(payload))"
Expose internet speed to home assistant¶
# We use the api to test our speed when we want
# curl -X POST "http://localhost:80/trigger?task=speedtest" -H "accept: application/json"
api:
port: 80
tasks:
- name: speedtest
pull:
plugin: pnp.plugins.pull.net.Speedtest
args:
interval: "0 6 * * *" # Run every morning at 6 am
push:
- plugin: pnp.plugins.push.mqtt.Discovery
selector: "data.get('download_speed_mbps')"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
object_id: speedtest_download
config:
name: "{{var::object_id}}"
icon: "mdi:cloud-download-outline"
state_topic: "{{var::state_topic}}"
unit_of_measurement: "Mbps"
- plugin: pnp.plugins.push.mqtt.Discovery
selector: "data.get('upload_speed_mbps')"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
object_id: speedtest_upload
config:
name: "{{var::object_id}}"
icon: "mdi:cloud-upload-outline"
state_topic: "{{var::state_topic}}"
unit_of_measurement: "Mbps"
- plugin: pnp.plugins.push.mqtt.Discovery
selector: "data.get('ping_latency')"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
object_id: speedtest_ping
config:
name: "{{var::object_id}}"
icon: "mdi:lan-pending"
state_topic: "{{var::state_topic}}"
unit_of_measurement: "ms"
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('server').get('name')"
attributes:
isp: "lambda data: data.get('client').get('isp')"
rating: "lambda data: data.get('client').get('rating')"
host: "lambda data: data.get('server').get('host')"
result_image: "lambda data: data.get('result_image')"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
object_id: speedtest_host
config:
name: "{{var::object_id}}"
icon: "mdi:cloud-sync-outline"
state_topic: "{{var::state_topic}}"
json_attributes_topic: "{{var::json_attributes_topic}}"
Fitbit to home assistant¶
# Polls your fitbit account for the step count and devices every 5 minutes
# and publishes those metrics to home assistant via mqtt discovery.
# https://www.home-assistant.io/docs/mqtt/discovery/
#
# Please point your environment variable `FITBIT_AUTH` to your authentication
# configuration file.
- name: fitbit_steps
pull:
plugin: pnp.plugins.pull.fitbit.Current
args:
config: !env FITBIT_AUTH
instant_run: true # Run as soon as pnp starts
interval: 5m
resources:
- activities/steps
push:
# Adds a sensor.fitbit_steps to home assistant
- plugin: pnp.plugins.push.mqtt.Discovery
selector: "data.get('activities/steps')"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
object_id: fitbit_steps
config:
name: "{{var::object_id}}"
icon: "mdi:soccer"
- name: fitbit_devices_battery
pull:
plugin: pnp.plugins.pull.fitbit.Devices
args:
config: !env FITBIT_AUTH
instant_run: true
interval: 5m
push:
# Adds sensor.fb_<device>_battery for each device attached to your fitbit account
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('battery_level')"
object_id: "lambda data: 'fb_{}_battery'.format(data.get('device_version', '').replace(' ', '_').lower())"
unwrap: true
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
config:
name: "{{var::object_id}}"
device_class: "battery"
unit_of_measurement: "%"
# Adds sensor.fb_<device>_lastsync for each device attached to your fitbit account
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('last_sync_time')"
object_id: "lambda data: 'fb_{}_lastsync'.format(data.get('device_version', '').replace(' ', '_').lower())"
unwrap: true
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
config:
name: "{{var::object_id}}"
Image face recognition¶
# Watches the directory '/tmp/camera' for file changes on image files and
# publishes them to a message queue (base64 encoded).
#
# Then the image data is pulled from the queue and a face recognition
# is executed. The result is a tagged file (known and unknown persons) which
# will be dumped to the specified directory.
#
- name: image_watcher
pull:
plugin: pnp.plugins.pull.fs.FileSystemWatcher
args:
path: "/tmp/camera"
events: [created]
ignore_directories: true
patterns: ['*.jpeg', '*.jpg', '*.png']
load_file: true
base64: true
push:
plugin: pnp.plugins.push.mqtt.Publish
selector: payload.file.content
args:
host: localhost
topic: camera/images
- name: image_processor
pull:
plugin: pnp.plugins.pull.mqtt.Subscribe
args:
host: localhost
topic: camera/images
push:
plugin: pnp.plugins.push.ml.FaceR
selector: b64decode(payload.payload)
args:
known_faces_dir: '/tmp/faces'
lazy: true
deps:
- plugin: pnp.plugins.push.simple.Echo
selector: (payload['known_faces'], payload['no_of_faces'])
- plugin: pnp.plugins.push.fs.FileDump
selector: payload['tagged_image']
args:
directory: '.'
extension: '.png'
Miflora to home assistant¶
# Polls a miflora device at :20 and publishes its reading
# to home assistant via mqtt discovery.
# https://www.home-assistant.io/docs/mqtt/discovery/
- name: miflora
pull:
plugin: pnp.plugins.pull.sensor.MiFlora
args:
mac: 'C4:7C:8D:67:50:AB' # The mac of your miflora device
instant_run: false
interval: '20 * * * *'
push:
- plugin: pnp.plugins.push.simple.Nop
selector: "data if data.get('conductivity') else SUPPRESS"
deps:
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('conductivity')"
object_id: "miflora_conductivity"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
config:
name: "{{var::object_id}}"
unit_of_measurement: "µS/cm"
icon: mdi:flash-circle
friendly_name: Conductivity
- plugin: pnp.plugins.push.simple.Nop
selector: "data if data.get('light') else SUPPRESS"
deps:
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('light')"
object_id: "miflora_light_intensity"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
config:
name: "{{var::object_id}}"
unit_of_measurement: "lx"
icon: mdi:white-balance-sunny
friendly_name: Light intensity
- plugin: pnp.plugins.push.simple.Nop
selector: "data if data.get('temperature') else SUPPRESS"
deps:
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('temperature')"
object_id: "miflora_temperature"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
config:
name: "{{var::object_id}}"
unit_of_measurement: "°C"
icon: mdi:thermometer
friendly_name: Temperature
- plugin: pnp.plugins.push.simple.Nop
selector: "data if data.get('battery') else SUPPRESS"
deps:
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('battery')"
object_id: "miflora_battery"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
config:
name: "{{var::object_id}}"
unit_of_measurement: "%"
device_class: battery
friendly_name: Battery
- plugin: pnp.plugins.push.simple.Nop
selector: "data if data.get('moisture') else SUPPRESS"
deps:
- plugin: pnp.plugins.push.mqtt.Discovery
selector:
data: "lambda data: data.get('moisture')"
object_id: "miflora_moisture"
args:
host: localhost
discovery_prefix: homeassistant
component: sensor
config:
name: "{{var::object_id}}"
unit_of_measurement: "%"
icon: mdi:water-percent
friendly_name: Moisture
Monitoring¶
# Client component
# Sends statistics about the host system (like cpu usage, ram usage, ...)
# to a mqtt broker every 30 seconds.
tasks:
- name: stats
pull:
plugin: pnp.plugins.pull.monitor.Stats
args:
interval: 30s
instant_run: true
push:
plugin: pnp.plugins.push.mqtt.Publish
args:
host: !env MQTT_HOST
topic: devices/my_name/stats
port: 1883
retain: true
# Each item of the payload-dict (cpu_count, cpu_usage, ...) will be pushed to the broker as multiple items.
# The key of the item will be appended to the topic, e.g. `devices/localhost/cpu_count`.
# The value of the item is the actual payload.
multi: true
# Server component
# Listens to the mqtt topic where the readings from each client are stored.
# If a new reading arrives it will be send to an influx database
# to save it for later evaluation.
tasks:
- name: stats_mqtt_pull
pull:
plugin: pnp.plugins.pull.mqtt.MQTTPull
args:
host: !env MQTT_HOST
topic: devices/+/stats/#
push:
plugin: pnp.plugins.push.timedb.InfluxPush
selector: "{'data': payload}"
args:
host: "localhost"
port: 8086
user: "the_user"
password: "the_password"
database: "my_db"
protocol: "{payload.levels[3]},device={payload.levels[1]},domain=stats value={payload.payload}"
Naive dropbox sync¶
# Every time a file is created or modified in /tmp
# the file is uploaded to dropbox and you are notified
# about it via pushbullet.
#
# You need to set your environment variables properly:
# - DROPBOX_API_KEY
# - SLACK_API_KEY
- name: dropbox_sync_notify
pull:
plugin: pnp.plugins.pull.fs.FileSystemWatcher
args:
path: "/tmp"
ignore_directories: true
events:
- created
- modified
load_file: false
push:
- plugin: pnp.plugins.push.storage.Dropbox
args:
api_key: !env DROPBOX_API_KEY
selector:
data: "lambda data: data.source" # Absolute path to file
target_file_name: "lambda data: basename(data.source)" # File name only
deps:
- plugin: pnp.plugins.push.notify.Slack
args:
api_key: !env SLACK_API_KEY # Your slack api key.
channel: test # The channel to post to. Mandatory. Overridable by envelope.
selector: data.raw_link