Giter VIP home page Giter VIP logo

pabiana's Introduction

Build Status

Pabiana

A smart home consists of various remotely controllable devices and sensors, all of which posses a distinct interface. These devices are controlled either manually with an app or by an adaptive algorithm based on sensor input. To be controllable from software each of these interfaces has to be represented in code. This demands for a particularly modular software design to be maintainable. Also, physical distances in larger smart homes call for a distributed control system.

Processing and integrating sensor input from various sources and of various types and controlling multiple devices based on the results, including feedback loops, can quickly get very complicated. A hierarchical data processing model can limit the complexity to a manageable degree. A hierarchical system control model on the other hand can enable steady monitoring and supervision of multiple semi-autonomous systems.

Pabiana is a minimalistic Python framework that lets you build software complying with these principles. Applications consist of a number of submodules running in parallel, distributed over several nodes. These modules are, however, closely interconnected. Constant streams of messages are passed between them as a means of communication. Messaging over the network is handled by the ØMQ library.

Besides home automation systems, Pabiana can be used to develop intelligent assistants, robot control systems or any other software that controls actuators based on sensory input.

Installation

Pabiana is currently tested with Python ≥ 3.5. It is hosted on PyPI. To integrate Pabiana into your projects, you can install it with:

pip install --upgrade pabiana

It is recommended to use a virtual environment for your project.

Application Design

The first step in the development of a Pabiana application is to think about the different submodules your application will be split in. At the bottom of the hierarchical structure you will usually find I/O modules for different media of communication. One module might be responsible for http, another one for UHF radio signals and a third one for audio signals. These modules rely strongly on resources like drivers provided by the operating system. However, they are rather generic and can be shared between applications. It might make sense to split input and output between two modules running in parallel if significant feedback loops occur within a medium of communication.

Upper modules receive input from lower ones. They integrate information from different communication media, as well as over time. These modules are responsible for representing reality and keeping track of it's state. For a home automation system, in this layer you might create a separate module for every important real-world device.

Top layer modules monitor actions and states of lower ones and intervene where necessary. They implement complex logic to orchestrate the interaction between devices.

Usage

Processes that run Pabiana modules are called areas. Each area can publish messages, subscribe to messages, trigger procedures of other areas and receive trigger calls. To start an area you have to use the following command:

python -m pabiana module_name:area_name

For this command to work, you have to provide a JSON file called interfaces.json in the working directory specifying the addresses for both networking interfaces of all the areas of your application. The structure of this file is as follows:

{
    "area1-pub": {"ip": "127.0.0.1", "port": 10001},
    "area1-rcv": {"ip": "127.0.0.1", "port": 10002},
    "area2-pub": {"ip": "127.0.0.1", "port": 10003},
    "area2-rcv": {"ip": "127.0.0.1", "port": 10004, "host": "0.0.0.0"}
}

In the current working directory there also has to be a folder called like the module and containing a Python file called __init__.py (a Python module). In this file you will define the functionality of the area.

from pabiana import Area, repo

area = Area(repo['area-name'], repo['interfaces'])
config = {
    'subscriptions': {'area2': ['ran', 'dom']}
}

@area.alteration(source='area2', slot='ran')
def input(recent, complete):
    print(recent)

@area.register
def procedure(parameter):
    area.publish({'foo': 'bar'}, slot='important')

This code creates an area that will listen to messages from area2 on two slots. If it receives messages from area2 it will print them. It's important to note that messages are queued for some time before they are processed together. A procedure is defined to be called from other areas. Return values for procedures are ignored. It is recommended to create a separate file for message handlers and procedures.

If a module requires a third-party library, it is possible to specify it in a requirements.txt file within the module directory. The specified libraries will be installed through Pip at start time. This feature was included to support automatic deployment of applications on different platforms.

pabiana's People

Contributors

alexschoeberl avatar

Watchers

 avatar  avatar

Forkers

bigflyingeagle

pabiana's Issues

Add testing framework

There should be a framework to easily test a single area or multiple areas locally. It should be possible to manipulate the input of tested areas.

Add subscriptions to context changes

The basic functionality of an area should look like this: If there was a change to any context values, call functions to calculate a new output. Context changes can be performed by other areas or from within the area. Both should result in a similar behavior.

Functions should be able to subscribe to changes in specific context values. These functions get called after every change to a subscribed value.

The basic functionality should closely resemble the behavior of a neural network (e.g. input -> output).

Send trigger as multipart message

At the moment, the trigger name is added to the parameters. Send the trigger name instead as the first part of a multipart message.

Message from unsubscribed slot results in TypeError

Area1 is subscribed to Area2 without a slot. If Area1 then receives a message from Area2 with a slot a TypeError will be thrown.

File "/pabiana/parsers.py", line 21, in imprint_full
  area.context[source][slot].appendleft(message)
TypeError: sequence index must be integer, not 'str'

Make use of pathlib

Port the code to make use of Python 3's pathlib throughout the project. This includes files like:

  • setup.py
  • __main__.py

Switch from modules to classes

Use classes instead of adding functions to an Area instance. Whether the functions have to be added to the instance can be discussed. A simple lookup table might be enough.

class A:
	trig = {}
	trac = []

	def __init__(self):
		self.trig = {}
		for trig in A.trig:
			self.trig[trig] = A.trig[trig].__get__(self, A)

	@staticmethod
	def register(func):
		A.trig[func.__name__] = func
		return func

	@staticmethod
	def note(func):
		A.trac.append(func.__name__)
		return func


class B(A):
	def __init__(self):
		super().__init__()
	
	@A.register
	def method1(self):
		pass

	@A.note
	def method2(self):
		pass

Received messages are not passed to functions

If you define an alteration function to listen to messages from an area, the message is not passed on to the function. You can access the message through the area.context variable, but not as a function parameter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.