Platypush

Platypush 1.0 is out

It's software maturity time

Published by Fabio Manganiello on May 26, 2024
.

It's been 10 months and 1049 commits since the latest release of Platypush, 7 years since the first commit, and 10 years since the first release of its ancestor, evesp.

The past few months have been quite hectic and I have nearly rewritten the whole codebase, but I feel like the software is now at a stage where it's mature and stable enough to be used by a larger audience.

The changelog is quite big, but it doesn't even cover all the changes, as many integrations have been completely rewritten.

Let's go over some of the changes in the 1.0 release.

All backends are gone or turned into plugins

Probably the most confusing feature of Platypush was the separation between backends and plugins.

This was a quirk of the original implementation, where plugins were pretty much stateless collections of actions and backends were background tasks that monitored a certain integration for new events.

It ended up in a state where users had to write the same configuration twice (e.g. one section for light.hue and one for backend.light.hue), and/or where me as a developer had to maintain tight dependencies between integrations in order for them to share configuration.

Those times are now gone. Backends should only do what backends are supposed to do - i.e. listen for external messages and dispatch them to the application. So the only ones that are still there are:

  • backend.http - the core Web server.

  • backend.nodered, to listen for messages from a Node-RED instance.

  • backend.redis, used internally to dispatch messages across components, and it can also be used by external scripts to dispatch application messages on localhost bypassing the HTTP layer.

  • backend.tcp, the legacy (and insecure) raw TCP listener.

Besides them, all the other backends have now been merged into their respective plugins, so no more need for dual configuration. If the former backend had a logic that polled at regular intervals, then you can disable polling in the plugin by setting poll_interval to null in the plugin configuration, so you can still use the plugin as a stateless entity if you wish so.

This is a quite big breaking change, so you may probably want to check out the plugins reference on the documentation to check for any configuration changes.

Better Docker support

There's now an official docker-compose.yml, as well as multiple Dockerfiles that support Alpine, Debian, Ubuntu and Fedora base images.

The platydock and platyvenv scripts have also been rewritten. They are now much more stable and smarter in installing any extra required dependency.

Official packages for several package managers

Official packages have been added for Debian and Fedora, on top of those available for Arch Linux.

Official Ubuntu packages are also on their way.

Better pip extras installation

Users previously had to dig through the setup.py file to get the pip extras supported by specific integrations.

Not anymore. Extra dependencies are now dynamically parsed from the integrations' manifest.json, so you can install them simply via pip install 'platypush[plugin1,plugin2,...]'.

For example, pip install 'platypush[light.hue,music.mpd]' to install the dependencies required by the light.hue and music.mpd plugins.

A more intuitive way of creating custom Python scripts

Simpler directory structure

Custom scripts are loaded as Python modules. This means that you need an __init__.py in each folder that hosts some Platypush custom scripts.

Earlier users were required to manually create that file, but that's no longer the case.

You can simply drop a .py file in any place under your scripts directory, with your procedures, event hooks, crons etc., and Platypush will automatically pick it up.

Simpler API

Earlier scripts relied on an API like this:

from platypush.message.event.something import SomeEvent
from platypush.event.hook import hook
from platypush.procedure import procedure
from platypush.utils import run

@procedure
def my_proc(**context):
  ...

@hook(SomeEvent)
def event_hook(event, **context):
  my_proc()

While this API is still supported, a new simplified version is now available too:

from platypush import procedure, when, run
from platypush.events.something import SomeEvent

# Note that custom procedure name overrides are now available, albeit optional
@procedure('this_is_my_proc')
# Arguments are no longer a requirement, either in procedure or hooks
def my_proc():
  ...

@when(SomeEvent)
# You can also omit event here if you don't need it
def event_hook(event):
  # Procedures can also be called directly via `run`
  run('procedure.this_is_my_proc')

Greatly improved documentation

The official documentation has been greatly expanded, and it now includes all the wiki content too as well as a better UI for the available integrations (and also a filter bar).

The documentation pages of the integrations have also been greatly improved to include ready-to-paste configuration snippets, installation commands for several package managers and a dynamically generated list of supported events and actions.

Removed all the custom Response objects

Removed all Response objects outside of the root type. They are now all replaced by Marshmallow schemas with the structure automatically generated in the documentation.

Some new cool integrations are in

The alarm plugin has been completely rewritten and paired to a powerful UI that allows you to set alarms as procedures.

The old stt.picovoice.* have been replaced by a new assistant.picovoice integration that provides all the features for a full-featured voice assistant.

The youtube plugin has been rewritten too, it now relies on yt-dlp and it uses Piped instances instead of the (brittle and unstable) YouTube API. It's also been paired with a new UI that makes it easy to navigate your feeds, subscriptions and playlists.

There's a new music.mopidy integration too, which takes some parts of the old music.mopidy backend and add a full plugin around it which is 100% compatible with the API of the music.mpd plugin, on top of a new UI for it. This makes it easier to switch between mpd and mopidy implementations for your music servers, and also leverage the asynchronous nature of Mopidy's Web socket API to get real time events without polling.

The camera.pi integration has been moved to camera.pi.legacy following the deprecation of the previous picamera library.

camera.pi is now a new integration based on the recent picamera2 module.

A new openai integration is now also available, making easy to programmatically get AI predictions anywhere. This can be particularly useful when paired with SST/TTS integrations like PicoVoice - you can implement custom voice assistants that use PicoVoice's libraries to do the speech/text conversion, and leverage ChatGPT's APIs to get plausible answers.

Some old stuff is out

google.fit has been removed, as Google announced the deprecation of the API (which has already experienced stability issues for a while anyway).

Same for weather.darksky, which has been purchased by Apple, which readily killed their amazing API. In turn, the weather.openweathermap integration has been empowered and it's compatible with the API of the former Darksky integration.

The wiimote integration is also out. The underlying cwiid library hasn't been updated in years, and it keeps struggling with Python 3 too.

Same fate goes for stt.deepvoice. DeepVoice was a very promising project from Mozilla to democratize speech-to-text, but it seems to be now abandoned, hasn't seen an update in years, and given Mozilla's financial woes it's unlikely to be resurrected any time soon.

I hope that the progress on the PicoVoice integration side will make up the loss of the DeepSpeech integration.

And there's more to come

There's a new voice integration based on Whisper/GPT-4o in the works too.

A dark theme for the UI.

A new Hue backend that can make Platypush emulate the API of a Philips Hue bridge and control devices from the Hue app or any compatible clients.

Support for more native entities from more plugins, so you can use the global entities view also to view cameras, control media players and run custom procedures.

And there are two big features in the work to support entity groups and entity scenes. These may not be must-have features anymore, now that all things can be customized with procedures, but it could greatly help those who come from other platforms and are used to these abstractions.

And if you have more requests or questions, feel free to open a ticket, a PR or ask on the Lemmy server.