Things Bus: Difference between revisions

From Pumping Station One
 
(12 intermediate revisions by 2 users not shown)
Line 10: Line 10:
There are 3 basic node types in things bus:
There are 3 basic node types in things bus:


* Sensors. Sensors produce data
* Sensors. Sensors produce data
* Actuators. Data Sinks consume data, and probably do something interesting with it.
* Actuators. Data Sinks consume data, and probably do something interesting with it.
* Neurons. Neurons take in sensory data, manipulate it in some way, and send the data to actuators.
* Neurons. Neurons take in sensory data, manipulate it in some way, and send the data to actuators.


=== Sensors ===
=== Sensors ===


A simple of an example of a sensor would be a temperature sense in the space. A temperature sensor would be a Raspberry Pi hooked into a temperature sense, and would send out the current temperature every 5 minutes.
A simple of an example of a sensor would be a temperature sense in the space. A temperature sensor would be a Raspberry Pi hooked into a temperature sense, and would send out the current temperature every 5 minutes.


Sensors make data available by using a zmq bind PUB socket.
Sensors make data available by using a zmq bind PUB socket.
Line 22: Line 22:
=== Actuators ===
=== Actuators ===


An Actuator is something that, when triggered, does something. It doesn't have to be physical. An actuator could be as simple as an led wired into a Raspberry Pi that can be triggered by a Neuron.
An Actuator is something that, when triggered, does something. It doesn't have to be physical. An actuator could be as simple as an led wired into a Raspberry Pi that can be triggered by a Neuron.


Actuators consume data by using a zmq bind PULL socket
Actuators consume data by using a zmq bind PULL socket
Line 41: Line 41:
Examples:
Examples:


* A Dust Collection Node would likely be both a sensor (Is it on?) and an actuator (Turn it on)
* A Dust Collection Node would likely be both a sensor (Is it on?) and an actuator (Turn it on)


== A Simple Example ==
== A Simple Example ==


The following is an example of a Neuron. It connects to sensory input, the hackerpspace's front and back doors, and sense data to an actuator, zirc, an actuator that writes data to #pumpingstationone on irc.freenode.net
The following is an example of a Neuron. It connects to sensory input, the hackerpspace's front and back doors, and sense data to an actuator, zirc, an actuator that writes data to #pumpingstationone on irc.freenode.net


Before running the example, you must have a recent python, recent libzmq installed, and must have pyzmq installed.
Before running the example, you must have a recent python, recent libzmq installed, and must have pyzmq installed.


    #!/usr/bin/env python
<syntaxhighlight lang="python">
    import zmq
#!/usr/bin/env python
import zmq
 
context = zmq.Context.instance()
 
# Create a zmq socket that will SUBscribe to door nodes.
door_socket = context.socket(zmq.SUB)
door_socket.connect("tcp://frontdoor.pumpingstationone.org:5556")
door_socket.connect("tcp://backdoor.pumpingstationone.org:5556")
 
# The doors send a lot of types of messages. We only care about "door.state.unlock" messages
door_socket.setsockopt(zmq.SUBSCRIBE, b"door.state.unlock")
 
# create a zmq socket that will PUSH data to our IRC actuator node.
zirc_socket = context.socket(zmq.PUSH)
zirc_socket.connect('tcp://sally.ad.pumpingstationone.org:5558')
 
# Loop forever
while True:
      
      
    context = zmq.Context.instance()
     # Read messages from the doors
   
    topic, message = door_socket.recv_multipart()
     # Create a zmq socket that will SUBscribe to door nodes.
 
    door_socket = context.socket(zmq.SUB)
     # Send the message to the irc channel
    door_socket.connect("tcp://frontdoor.pumpingstationone.org:5556")
    zirc_socket.send(message)
    door_socket.connect("tcp://backdoor.pumpingstationone.org:5556")
</syntaxhighlight>
   
    # The doors send a lot of types of messages. We only care about "door.state.unlock" messages
    door_socket.setsockopt(zmq.SUBSCRIBE, b"door.state.unlock")
   
    # create a zmq socket that will PUSH data to our IRC actuator node.
    zirc_socket = context.socket(zmq.PUSH)
    zirc_socket.connect('tcp://sally.ad.pumpingstationone.org:5558')
   
    # Loop forever
    while True:
   
        # Read messages from the doors
        topic, message = door_socket.recv_multipart()
      
        # Send the message to the irc channel
        zirc.send(message)


== Hardware ==
== Hardware ==


We are targetting Beagle Bone Blacks for node hardware. While in theory, the hardware can be anything, having a consistent dev platform is useful.
We are targetting Beagle Bone Blacks for node hardware. While in theory, the hardware can be anything, having a consistent dev platform is useful.


The BBB has 2 blocks of GPIO lines, and the capability of supporting up to 4 Serial devices. A lot of the types of data we want to collect are available over gpio and serial.
The BBB has 2 blocks of GPIO lines, and the capability of supporting up to 4 Serial devices. A lot of the types of data we want to collect are available over gpio and serial.


==Things Bus Broker ==
== Things Bus Broker ==


For certain types of nodes, a broker that maintains state is useful.
For certain types of nodes, a broker that maintains state is useful.  
For details of this system, see https://github.com/eastein/thingsbus
For details of this system, see https://github.com/eastein/thingsbus


== Communication ==
== Inter-Node Communication ==
 
{{ambox
|type=content
|text=The code snippits contain errors
}}


The software for a node can be written in any language that supports zmq and json.
The software for a node can be written in any language that supports zmq and json.


Nodes send messages using json data. Sensors use zmq PUB/SUB. Actuators use zmq PUSH/PULL. Neurons use whatever they have to do get the job done, which means they SUB to sensors, and PUSH to actuators.
=== Code Snippits ===
Sensors send data like this:
Sensors send data like this:


    import zmq
    context = zmq.Context.instance()
     socket = context.socket(zmq.PUB)
     socket = context.socket(zmq.PUB)
     socket.Bind('tcp://*:5556')
     socket.bind('tcp://*:5556')
     socket.send_multipart(('dot.delimited.filter', '{"json":"message"}'))
     socket.send_multipart(('dot.delimited.filter', '{"json":"message"}'))


Neurons receive data like this:
Neurons receive data like this:


    import zmq
    context = zmq.Context.instance()
     sensor = context.socket(zmq.SUB)
     sensor = context.socket(zmq.SUB)
     sensor.connect("tcp://sensor.tld:5556")
     sensor.connect("tcp://sensor.tld:5556")
    sensor.setsockopt(zmq.SUBSCRIBE, b"dot.delimited.filter")
     topic, message = sensor.recv_multipart()
     topic, message = sensor.recv_multipart()
     data = json.loads(message)
     data = json.loads(message)
Line 105: Line 120:
Neurons send data like this:
Neurons send data like this:


    import zmq
    context = zmq.Context.instance()
     actuator = context.socket(zmq.PUSH)
     actuator = context.socket(zmq.PUSH)
     actuator.connect('tcp://actuator.tld:5558')
     actuator.connect('tcp://actuator.tld:5558')
Line 111: Line 128:
Actuators receive data like this:
Actuators receive data like this:


    import zmq
    context = zmq.Context.instance()
     socket = context.socket(zmq.PULL)
     socket = context.socket(zmq.PULL)
     socket.bind('tcp://*:5558')
     socket.bind('tcp://*:5558')