Close
0%
0%

Switchboard: Distributed Automation made Easy

A small Python framework for the tinkerer to make distributed automation as simple as possible

Similar projects worth following
IoT automation is conceptually simple, for example: when (a) happens do (b) and wait 3 seconds before also doing (c). But what if (a) comes from a Raspberry Pi, (b) is a desktop computer and (c) an ESP8266 WiFi module? Who should be in charge of controlling this functionality? What should we do if WiFi becomes temporarily unavailable?

These are a few of the many hard questions I had to ask myself when deciding how to connect my devices together in a meaningful way. To this end I've been slowly piecing together a Python framework called Switchboard which takes care of device connectivity, availability, is easy to write logic for and is dynamically configurable through a command line interface.

Motivation

With existing offerings such as openHAB, Home Assistant and Vera, do we need yet another automation hub/framework/solution? Depends on your needs. Switchboard has a combination of features that make it unique and very powerful if you mostly want to automate and not just remote control your devices on a local network:

  • Low-key solution that is small, simple and extremely easy to setup and configure
  • Fine-grain control over devices
  • All the data stays on your local network (unless you serve it to the outside world)
  • No reliance on a stable internet connection (I live in Australia)
  • Perfect for the tinkerer: easy to create and debug your devices
  • No complex rules that are hard to configure. Just inputs, outputs, and the full power of the Python programming language to do whatever you want
  • Automate pretty much anything, not just your home (e.g., automated flower-watering system)

Downsides: at this early stage there aren't 1000 libraries to connect to a 1000 commercially available devices, a mobile app etc. (yet), A certain amount of programming skill is required.

Technical Details

Switchboard functionality and features:

  • the Switchboard framework runs on a base station (x86 computer or Raspberry Pi)
  • polls Switchboard clients via a simple HTTP REST Api
  • input and output devices can be directly read from and written to by a Switchboard module, which is effectively a function with a decorator
  • writing a Switchboard module is DEAD EASY: 1) specify a decorator with the desired inputs and outputs, 2) specify arguments to match the inputs and the outputs and 3) write your logic, knowing that all the connectivity is taken care of
  • Python and C++ ESP8266 Switchboard client libraries (maybe also Arduino with an Ethershield if I get round to it)
  • resilient to network outage (outputs are set to given 'error state' value)
  • easy to use command line prompt for dynamic Switchboard configuration: adding, updating or removing a piece of functionality is performed without affecting unrelated devices and modules

Switchboard Modules

Switchboard modules are evaluated/executed at every cycle (set by the polling period) unless one of the module IOs reports an error. In case of error, all the outputs are set to their error state as specified in the module decorator. An output signal can only be driven by one single module. In order to keep the modules self-contained decorators can specify static variables.

Or, in FPGA jargon: a Switchboard module is much like a synchronous HW entity on an FPGA, where the clock is defined by the polling period and the static variables are the registers.

License

Licensed under the MIT License

  • Switchboard Modules Explained

    josefschneider05/31/2017 at 21:33 0 comments

    Skip the first video and go straight to this one: a quick dive into the anatomy of a Switchboard Module together with a demonstration!

  • Spring Clean

    josefschneider05/30/2017 at 20:37 0 comments

    After focusing mostly on fun features for the last few weeks I sat down and did some of the less exciting stuff.

    We finally have a 'remove' command which can be used to remove clients or modules.

    It is now possible to give clients (but not yet client apps) a poll period in case this particular client doesn't need to be updated all that often, e.g., a room temperature sensor does not need to be read every second.

    The updateclient command can be used to change the client poll period at runtime.

    Client/device/module statuses are now printed (in colour!) when running the 'list' command.

    Significantly improved reliability and error reporting.

    If you fancy trying Switchboard out yourself I would be very grateful for any bug reports, crash reports, general feedback or suggestions!

  • First Video!

    josefschneider05/21/2017 at 15:36 0 comments

    Going over the basics...


  • InfluxDB App

    josefschneider05/20/2017 at 13:59 0 comments

    InfluxDB (https://www.influxdata.com/) is a time-series database perfectly suited for the storage of sensor values, and because it provides a Python client library I was able to write an IOData agent app. I'm very keen on InfluxDB because it is natively supported by Grafana (https://grafana.com/), a beautiful, flexible data visualisation suite. After installing InfluxDB and Grafana and launching the swb_influxdb_save app all the Switchboard device values are automatically stored. When creating the following dashboard I was able to select the devices I wanted to plot from a drop-down menu:

    At around 13:53:40 I blew on the DHT22 sensor causing the spikes in humidity and temperature. Grafana comes with a bit of a learning curve, but it is so powerful and flexible that you won't regret looking into it.

    As usual, a rough guide on how to setup this app can be found in the repo in the apps/swb_influxdb_save/README.md file.

  • Apps... and IKEA Tradfri Support!

    josefschneider05/17/2017 at 05:49 0 comments

    Apps are standalone executables that can be configured, launched and terminated by Switchboard. The only requirement for an app is that it support a "--getconf" argument which prints to stdout a JSON representation of the app input arguments. For example, for the swb_system_info app, "--getconf" would return the following:

    {"Client port": {"args": ["--client_port", "-cp"], "kwargs": {"help": "Switchboard client listening port"}}}

    This allows Switchboard to know that this app has a "--client_port" argument. Switchboard knows what to do with this specific argument and silently populates it with an unused port number. This is followed by a silent "addclient" command so all the swb_system_info inputs are immediately available.

    To make it easier to develop python Switchboard apps there are three classes to help you out: ClientApp (as per last log entry), IODataApp which gets a stream of all device value data, and ClientIODataApp in case you need both sets of functionality. All the app arguments are saved in the Switchboard config so that apps can automatically be launched at startup. Switchboard currently comes with a few apps out of the box, which are swb_system_info, swb_dashboard, swb_io_file_save, and... swb_tradfri!

    IKEA Tradfri are cheap wireless lightbulbs for which you can control on/off, brightness and colour temperature (for the more expensive models). To get the lightblubs working you need at least one Tradfri LED bulb, one steering device and one network gateway, and you need to set them up through the IKEA Tradfri app. Install the coap-client (instructions in apps/swb_tradfri/README.md) on your Linux machine and you're ready to go:

    Enter the gateway IP, the security code and a client alias and voilà! The app automatically detects all the connected devices and creates outputs to control them: we can power on/off and dim a group of bulbs with the group_<group id>_<action>.o outputs, and control each bulb individually with the bulb_<group id>_<bulb id>_<action>.o outputs. So to turn on a bulb, you only need to type:

    set tradfri.bulb_0_0_power 1

  • New and improved: Switchboard Clients

    josefschneider05/09/2017 at 19:22 0 comments

    Writing a Switchboard client has gotten even easier. The ClientApp class takes care of parsing application arguments and starting the server. "--client_port" is now a mandatory argument, and specifies the port on which the client is listening. As an example, it is now possible to create a client that publishes CPU and memory usage, all within 15 lines:

    #!/usr/bin/env python
    import psutil
    from client_app import ClientApp
    from switchboard_client.client import SwitchboardInputDevice
    
    def main():
        app = ClientApp()
        app.add_device(SwitchboardInputDevice('cpu_usage.i', lambda: psutil.cpu_percent()))
        app.add_device(SwitchboardInputDevice('memory_usage.i', lambda: psutil.virtual_memory().percent))
        app.run()
    
    if __name__ == "__main__":
        main()
    

    The latest code changes include a swbc_system_info app very similar to the example. It becomes available as a terminal application after installing Switchboard. To run it type

    swb_system_info --client_port <port_number>
    
    where <port_numer> is the port you want the client to listen on. Because the client data is made available through a simple HTTP get request you can see part of its interface in a browser. Open a tab and enter the following address:
    localhost:<port_number>/devices_info

    This displays the devices that are available from this Switchboard client. To get the values have a look at:

    localhost:<port_number>/devices_value

    The best thing about ClientApps is that it provides all clients with common functionality we'll be exploiting very shortly!

  • Introducing: IOData Agents

    josefschneider05/06/2017 at 17:36 0 comments

    IoT is not only about controlling but also about measuring. Since Switchboard provides a means to connect many devices in a centralised manner, it would be a shame not to provide some interface through which we can collect the device data and do things with it, such as storing it or displaying it.

    To this end I have just added a component to Switchboard called IOData. At every polling cycle IOData receives an update of all the device states. IOData then proceeds to determine what the value differences are between the current and the previous cycles and encodes those differences as an array of updates.

    This is where IOData Agents come in. An agent is an app that subscribes to the IOData update stream. What it does with this data is entirely up to the agent. Switchboard currently comes with two agents out of the box:

    • IOFileSave: stores the list of updates in a file. Can be configured to only store a maximum number of updates, deleting the oldest entries if we reach this number
    • Dashboard: an HTML dashboard that uses websockets to always display the latest device value data:

    To launch the Dashboard agent enter the following command:

    launchapp swb_dashboard
    after which you will be prompted for the port on which to run the server. All agent settings are automatically stored in the config file.

  • We have an example!

    josefschneider04/25/2017 at 21:08 0 comments

    I managed to fix a bunch of bugs to do with functionality I hadn't run in a while, and have also added a simple example showing the absolute minimum required to get a Switchboard setup working. The example files consist of an input client, an output client, a test module that simply multiplies the input, and a settings file so that everything is ready to go.

    The one things missing here is a list of commands (which I shall be adding to the readme shortly), but the command line interface comes with '-help' functionality and tab-completion and is rather simple.

    Next steps:

    • creating a functional HTML dashboard
    • creating a video of the whole thing in action
    • adding features and unit tests

  • Publishing the Code

    josefschneider04/22/2017 at 10:35 0 comments

    I finally got round to uploading the source files to Github. I ran the Switchboard application using python3 on a Linux machine and everything worked as expected. Not fully tested at this stage, so I wouldn't be surprised if some of the more fancy features (e.g., on-the-fly module update) would cause the application to crash.

    So far we have the main repository https://github.com/josefschneider/switchboard which contains the framework complete with command line interface, and a switchboard client module to easily instantiate switchboard hosts.

    The https://github.com/josefschneider/esp8266switchboardclient repository contains a C++ library that turns an ESP8266 into a Switchboard client using the ESP8266WebServer and ArduinoJson libraries.

    Next steps:

    • adding example code to the repository
    • adding a short tutorial to the readme files
    • creating a video of the whole thing in action
    • adding features and unit tests

View all 9 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates